【问题标题】:lambda to curl callback functionlambda 到 curl 回调函数
【发布时间】:2015-04-13 02:13:17
【问题描述】:

我正在尝试将 lambda 传递给 CURLOPT_WRITEFUNCTION。

该函数需要一个静态函数,但是,我从 this question 了解到 lambda 将被隐式转换,我可以从 lambda 调用成员函数。

auto callback = [](char * ptr_data, size_t size, size_t nmemb, string * writerData)
->size_t
{
    if(writerData == NULL)
        return 0;
    size_t data_size = size * nmemb;
    writerData->append(ptr_data, data_size);
    return (int)data_size;
};

CURLcode code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, callback);

这实际上可以编译,但是 curl 段错误:Segmentation fault: 11

我粘贴了完整的示例here。

【问题讨论】:

  • 看着你的 sn-p,你不希望:code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer); 在你调用 CURLOPT_WRITEFUNCTION 之前被调用吗?否则不会设置传递给回调的指针。
  • @JesseGood,顺序无关紧要,只要我在调用curl_easy_perform之前设置它们。

标签: c++ c++11


【解决方案1】:

我只是用libcurl写了类似的lambda,然后崩溃了,仔细检查后,我得到了follow code的工作原理。

神奇的是,在未捕获的 lambda 表达式中添加前导“+”,这将触发转换为纯 C 函数指针。

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
  /* NOTE: Leader '+' trigger conversion from non-captured Lambda Object to plain C pointer */
  +[](void *buffer, size_t size, size_t nmemb, void *userp) -> size_t {
    // invoke the member function via userdata
    return size * nmemb;
  });

我的理解是,curl_easy_setopt() 需要一个 void*,而不是显式函数类型,所以编译器只给出 lambda OBJECT 的地址;如果我们对 lambda 对象进行函数指针操作,编译器会从 lambda 对象返回函数指针。

【讨论】:

    【解决方案2】:

    只有在 lambda 没有捕获时才能将 lambda 闭包转换为函数指针。

    您的 lambda 正在捕获 [this],因此无法转换。

    编辑:这是对问题原始版本的回答。

    【讨论】:

    • 虽然不是 curl 特定的,但 these 其他 questions 是相似的。
    • 查看我的编辑,我知道这一点,并且正在测试不同的配置,因为 curl 在所有情况下仍然存在段错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    相关资源
    最近更新 更多