[英]libcurl/cURL c++ segfault
我正在尝试编写一个类,以便使用cURL从C ++网站中获取一些数据。 这是该类的示例(有一个Curl * curl_数据成员,rawData_是一个字符串)。 此摘录来自实现文件,所有函数均在标头中声明。
MyClass::MyClass()
{
curl_global_init(CURL_GLOBAL_ALL);
curl_ = curl_easy_init();
curl_easy_setopt(curl_, CURLOPT_URL,
"http://www.google.com");
curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, &MyClass::writeCallback);
}
MyClass::~MyClass()
{
curl_easy_cleanup(curl_);
curl_global_cleanup();
}
size_t MyClass::writeCallback(char* buf, size_t size, size_t nmemb, void* up)
{
//buf is a pointer to the data that curl has for us
//size*nmemb is the size of the buffer
for (size_t c = 0; c<size*nmemb; ++c)
{
cerr << c << endl;
rawData_.push_back(buf[c]);
}
return size*nmemb; //tell curl how many bytes we handled
}
void MyClass::makeCall()
{
curl_easy_perform(curl_);
}
当我创建MyClass的实例并调用makeCall时,writeCallBack函数中存在一个段错误。 即,buf的大小似乎为0(当c = 0时,buf [c]的调用会中断)。 任何帮助表示赞赏
带有CURLOPT_WRITEFUNCTION
curl_easy_setopt
的参数应该是size_t function( char *ptr, size_t size, size_t nmemb, void *userdata)
类型size_t function( char *ptr, size_t size, size_t nmemb, void *userdata)
。 那是“干净的” C函数,而不是方法。
但是据我所知,您正在传递一个非静态方法的地址。 因此它将没有正确的签名(我猜它是非静态的,因为您在其中使用rawData_
)。
现在, curl_easy_setopt
并不真正在乎-它需要您提供的一切。 但是,当调用该函数时,会发生不好的事情。
我的建议是将writeCallback
声明为静态(或什至作为非成员朋友)并将用户数据设置this
(使用curl_easy_setopt
与CURLOPT_WRITEDATA
)。 然后,您可以将userdata参数转换为MyClass
并在函数内部使用它。
在解释了CURLOPT_WRITEFUNCTION
的libcurl手册页curl_easy_setopt
中,它指出在某些情况下可以使用“零大小”来调用该回调,例如表示响应为空。 在那种情况下,至少size*nmemb
应为零,因此您的循环永远不会输入空缓冲区,因此在那里应该是安全的。
然而,它也描述了参数CURLOPT_WRITEFUNCTION
作为拍摄功能与给定的参数,而不是一个C ++成员函数。 很有可能是您在回调成员函数体内的隐式this
指针被解释为buf
。 碰巧的是, this
(内部类状态)在崩溃的同一行上首次被取消引用: rawData_.push_back(buf[c])
。
很快,请尝试将您的类成员函数回调转换为静态函数回调(即,不再是MyClass
的成员)。 那应该工作。 然后,您可以将此函数用作MyClass
的friend
,或者如果在使用curl_easy_setopt
设置回调时将适当的this
指针传递给CURLOPT_WRITEDATA
选项,则可以将调用代理到类成员函数,从而允许使用静态非成员函数用适当的指向类对象的指针来调用适当的C ++类方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.