将额外参数传递给 libcurl CURLOPT_READFUNCTION 回调

发布于 2024-12-14 04:36:29 字数 1999 浏览 1 评论 0原文

程序

读出文本文件并通过电子邮件发送其内容

原始代码(在Sehe的帮助下)

https://gist.github.com/1342118#file_test.cpp

问题:

我尝试多次运行该应用程序使用线程,为每个线程使用不同的文本文件。这意味着我不能再使用全局向量,因为线程 3 可能会在线程 1 仍在处理该向量时添加/更改该向量。这意味着这一行变得有问题:

curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);

这调用了这个函数:

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
  struct WriteThis *pooh = (struct WriteThis *)userp;

  if(size*nmemb < 1)
    return 0;

  if (pooh->counter < text.size())
  {
      const std::string& data = text[pooh->counter];

      memcpy(ptr, data.data(), data.length());
      pooh->counter++; /* advance pointer */
      return data.length();
  }
  return 0; /* no more data left to deliver */
}

正如您所看到的,它使用全局定义的向量“文本”。我以为我可以通过简单地在该函数(read_callback)中创建向量来修复它,但由于我现在使用线程,文件名不再是硬编码的,所以我最终不得不传递一个变量。

Curl 似乎填充了 read_callback 自动接受的变量,那么这是如何完成的呢?

只是为了澄清一下,这就是我现在所拥有的:

std::vector<string> read_text(char* fname)
{
    std::ifstream myfile (fname);
    std::vector<string> text;

    std::string line;
    while (std::getline(myfile, line))
    {
        text.push_back(line + '\n');
    }

    return text;
}

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{

    std::vector<string> text;
    text = read_text(textfilename);

  struct WriteThis *pooh = (struct WriteThis *)userp;

  if(size*nmemb < 1)
    return 0;

  if (pooh->counter < text.size())
  {
      const std::string& data = text[pooh->counter];

      memcpy(ptr, data.data(), data.length());
      pooh->counter++; /* advance pointer */
      return data.length();
  }
  return 0; /* no more data left to deliver */
}

但是 read_text 不起作用,因为 textfilename 尚未传递给该函数。

The program

Reads out a textfile and emails it's contents

The original code (with help of Sehe)

https://gist.github.com/1342118#file_test.cpp

The problem:

I am trying to run the application multiple times using threading, using a different textfile for each thread. This means I can no longer use a global vector because thread 3 may add to / alter this vector while thread 1 is still working on it. This means this line is becoming problematic:

curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);

This calls this function:

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
  struct WriteThis *pooh = (struct WriteThis *)userp;

  if(size*nmemb < 1)
    return 0;

  if (pooh->counter < text.size())
  {
      const std::string& data = text[pooh->counter];

      memcpy(ptr, data.data(), data.length());
      pooh->counter++; /* advance pointer */
      return data.length();
  }
  return 0; /* no more data left to deliver */
}

As you can see it uses the globally defined vector "text". I thought I could fix it by simply making the vector inside that function (read_callback) but since I'm using threading now, the filename is no longer hard coded so I end up having to pass a variable anyway.

Curl seems to fill in the variables that read_callback accepts automatically so how is this done?

Just to clarify, here's what I have now:

std::vector<string> read_text(char* fname)
{
    std::ifstream myfile (fname);
    std::vector<string> text;

    std::string line;
    while (std::getline(myfile, line))
    {
        text.push_back(line + '\n');
    }

    return text;
}

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{

    std::vector<string> text;
    text = read_text(textfilename);

  struct WriteThis *pooh = (struct WriteThis *)userp;

  if(size*nmemb < 1)
    return 0;

  if (pooh->counter < text.size())
  {
      const std::string& data = text[pooh->counter];

      memcpy(ptr, data.data(), data.length());
      pooh->counter++; /* advance pointer */
      return data.length();
  }
  return 0; /* no more data left to deliver */
}

But read_text doesn't work because textfilename hasn't been passed to the function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

缱倦旧时光 2024-12-21 04:36:29

再次仔细阅读 curl_easy_setopt 的文档。您可以将 CURLOPT_READDATA 设置为您的 textfilename 并强制转换 userp 以将其放入您的 read_callback

edit

您的 userp 已实际使用;因此,您应该将 textfilename 添加到 WriteThis struct 的新字段中。大多数回调函数只接受一个用户数据,但这应该足够了(因为您可以在其中打包任意内容)。

Read carefully again curl_easy_setopt's documentation. You might set the CURLOPT_READDATA to your textfilename and cast the userp to get it inside your read_callback

edit

Your userp is actually used; so you should add the textfilename in a new field of your WriteThis struct. Most callback functions take only one user data, but it should be enough (since you can pack arbitrary stuff in it).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文