rra*_*alf 5 c++ lambda curl callback c++11
在 C++11 项目中,我使用的是 C 风格的第三方库(在我的例子中是 curl),它需要 C 风格的回调。
为了实现这一点,我使用了“指针到成员”运算符:
size_t c_callback_wrapper(char *ptr, size_t size, size_t nmemb, void *userdata)
{
MyClass *p = (MyClass*)userdata;
return (p->*&MyClass::actualCallback)(ptr, size, nmemb, userdata);
}
void Myclass::performSomething() {
// register callback function
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, c_callback_wrapper);
// register userdata
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
...
res = curl_easy_perform(curl);
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案确实有效,但对我来说并不令人满意。
我真正想做的是在我的注册函数中编写一个 lambda。
优势通常是局部性:我将能够捕获一些局部变量,并且无需编写复杂的“actualCallback”成员例程。
我已经读过,当 Lambda 捕获变量时,似乎不可能将它们用作 C 风格的函数。
有什么方法可以使用一些技巧来实现这一目标吗?(例如玩 lambdas 的调用约定,...)
谢谢
无法将捕获上下文变量的 lambda 转换为裸函数指针,因为这将无法携带捕获的状态。您在示例中展示的是处理通过 C 回调调用 C++ 成员函数的问题的正确方法。
c_callback_wrapper如果您发现更吸引人,您可以替换为捕获较少的 lambda。
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
[](char *ptr, size_t size, size_t nmemb, void *userdata) {
// invoke the member function via userdata
auto p = static_cast<MyClass *>(userdata);
return p->actualCallback(ptr, size, nmemb, userdata);
});
Run Code Online (Sandbox Code Playgroud)
请注意,您可能应该去掉actualCallback()成员函数的最后一个参数,因为那只是this指针,非静态成员函数不需要显式传递指针。