Libcurl回调w/c++类成员
libcurl callbacks w/c++ class members
摘自libcurl网站上的libcurl编程教程:
libcurl with c++
在使用c++时,基本上只需要记住一件事当连接libcurl:
时,而不是C回调函数不能是非静态类成员函数
示例c++代码:
class AClass { static size_t write_data(void *ptr, size_t size, size_t nmemb, void ourpointer) { /* do what you want with the data */ } }
这个限制是为了什么,是作用域的问题吗?如果每个类成员都有自己的easy_handle,那么它可以使用回调到它自己的非静态成员函数吗?它没有继续说。我可以用这两种方式工作,但我很好奇为什么它存在。
编辑:还有一件事;这是否对从类中创建easy_handle施加了限制?如果是这样的话,我希望每个对象都有自己的easy_handle
非静态成员函数通常不允许作为C回调,因为它还需要实例指针作为隐藏参数,这是调用C代码不提供的(并且这个隐藏参数,取决于编译器,可能不会根据"常规"调用约定传递,而是在特定的寄存器中,…)。
相反,静态成员函数是具有特定作用域的"普通"函数(就ABI而言,这是不相关的)。要调用实例方法,您需要一个实例来调用它。接受函数指针的libcurl函数不接受对象指针(确切地说,不能接受对象指针,因为它们是C函数),因此无法传递调用实例方法所需的数据。
你可以通过userdata
参数传递一个实例指针,然后使用它来调用实例方法:
class AClass {
public:
static size_t invoke_write_data
(void *data, size_t size, size_t nmemb, void* pInstance)
{
return ((AClass*)pInstance)->write_data(ptr, size, nmemb);
}
size_t write_data(void *data, size_t size, size_t nmemb) {
/* ... */
}
};
...
extern AClass instance;
curl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, AClass::invoke_write_data);
curl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, &instance);
如果您需要通过userdata
参数传递更多数据,请使用包含实例指针作为成员的结构体。注意内存管理:参数结构可能会泄漏或被提前回收。
当c++ 0x成为标准并被编译器支持时,你应该能够使用闭包来绑定实例和实例方法,传递一个匿名函数作为回调。
参见:"如何将指向成员函数的指针传递给信号处理程序、X事件回调、启动线程/任务的系统调用等?",来自c++常见问题解答
相关文章:
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 助记符和指向成员语法的指针
- 用于访问容器<T>数据成员的正确 API
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 嵌套在类中时无法设置成员数据
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 将函数类成员映射到类本身内部
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- 多成员Constexpr结构初始化
- 我们可以访问一个不存在的联盟的成员吗