我可以将libcurls CURLOPT_WRITEFUNCTION与C ++ 11 lambda表达式一起使用吗?

时间:2011-07-08 12:50:21

标签: c++ lambda c++11 libcurl

我尝试使用带有CURLOPT_WRITEFUNCTION的C ++ 11 lambda表达式,但程序在运行时因访问冲突而崩溃。由于缺乏C ++ 11知识,我不确定如何进一步研究这个问题,但也许其他人知道如何使这项工作。

功能:

#ifndef CURL_GET_H
#define CURL_GET_H

#include <curl/curl.h>
#include <curl/easy.h>
#include <vector>
#include <string>

std::vector<std::string> curl_get(const char* url)
{
    CURL *curl;
    CURLcode res;

    std::vector<std::string> content;
    auto curl_callback = [](void *ptr, size_t size, size_t nmemb, void *stream) -> size_t {
        // does nothing at the moment due to testing...
        return size * nmemb;
    };

    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/aaa.txt");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }

    return content;
}

#endif // CURL_GET_H

错误:

  

Unphandelte Ausnahme bei 0x000000cc in lpip_dl.exe:0xC0000005:Zugriffsverletzung bei位置0x00000000000000cc。

     

(位置0x00000000000000cc处的访问冲突)

当curl想要使用回调时发生:

wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);

4 个答案:

答案 0 :(得分:8)

你实际上可以通过将lambda函数转换为函数指针来实现。你可以先制作一个typedef来简化演员表。

typedef size_t(*CURL_WRITEFUNCTION_PTR)(void*, size_t, size_t, void*);

然后你使用static_cast。

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, static_cast<CURL_WRITEFUNCTION_PTR>(curl_callback));

注意:为了转换为C函数指针,您只能使用空捕获[]。

答案 1 :(得分:1)

libcurl是普通的C库,你需要设置一个可以从这样调用的回调。这意味着有趣的C ++事物需要首先“C”化才能工作。喜欢进入旧式函数指针。

这也在libcurl FAQ条目“Using C++ non-static functions for callbacks?

中得到解决

另请参阅:C-style Callbacks in C++11

答案 2 :(得分:0)

在Linux中将lambda投射到适当的函数指针对我来说很有效:

auto curl_callback = static_cast<size_t(*)(char*,size_t,size_t,void*)>([](...){...});

答案 3 :(得分:0)

这可以通过+前缀完成,该前缀返回C样式的函数指针。但这仅适用于无状态lambda(空捕获列表,即[])。

auto lambda = +[](void *ptr, size_t size, size_t nmemb, void *stream) -> size_t {
    // does nothing at the moment due to testing...
    return size * nmemb;
};

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, +[](void *ptr, size_t size, size_t nmemb, void *stream) -> size_t {
    // does nothing at the moment due to testing...
    return size * nmemb;
});