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

发布于 2024-11-19 11:42:05 字数 1249 浏览 2 评论 0原文

我尝试将 C++11 lambda 表达式与 CURLOPT_WRITEFUNCTION 结合使用,但程序在运行时因访问冲突而崩溃。由于缺乏 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

错误:

lpip_dl.exe 中的 Unbehandelte Ausnahme bei 0x000000cc:0xC0000005:Zugriffsverletzung bei 位置 0x00000000000000cc。

(位置 0x00000000000000cc 处发生访问冲突)

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

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

I tried to use a C++11 lambda expression with CURLOPT_WRITEFUNCTION, but the program crashes at runtime with an access violation. I'm not sure how to look further into this due to lack of C++11 knowledge, but maybe someone else has an idea how to make this work.

The function:

#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

The error:

Unbehandelte Ausnahme bei 0x000000cc in lpip_dl.exe: 0xC0000005: Zugriffsverletzung bei Position 0x00000000000000cc.

(Access violation at position 0x00000000000000cc)

Happens when curl wants to use the callback:

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

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

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

发布评论

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

评论(4

柒七 2024-11-26 11:42:05

实际上,您可以通过将 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函数指针,只能使用空的captures[]。

You actually can do that by casting the lambda function to function pointer. You can first make a typedef to make cast easier.

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

Then you use static_cast.

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

Note: In order to convert to C function pointer, you can only use empty captures [].

温柔少女心 2024-11-26 11:42:05

这可以通过 + 前缀来完成,它返回一个 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;
});

This can be done with the + prefix, which returns a C-style function pointer instead. But this only works with stateless lambdas (empty capture list i.e. []).

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;
};

or

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;
});
人生百味 2024-11-26 11:42:05

libcurl 是纯 C 库,您需要设置一个可以从此类库调用的回调。这意味着有趣的 C++ 东西需要首先“C'ified”才能工作。就像旧式的函数指针一样。

libcurl 常见问题解答条目“使用 C++ 非静态函数进行回调?

另请参阅:C++11 中的 C 风格回调

libcurl is plain C library, you need to set a callback that can be called from a such. This means funny C++ things need to be "C'ified" first to work. Like into an old-style function pointer.

This is also addressed in the libcurl FAQ entry "Using C++ non-static functions for callbacks?"

See also: C-style Callbacks in C++11

雨落□心尘 2024-11-26 11:42:05

在 Linux 中,将 lambda 转换为正确的函数指针对我来说很有效:

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

Casting the lambda to the proper function pointer works for me in Linux:

auto curl_callback = static_cast<size_t(*)(char*,size_t,size_t,void*)>([](...){...});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文