使用libcurl和curlcpp存储收发数据及header,解决DEBUGFUNCTION编译报错问题
问题根源
非静态类成员函数的函数指针和C语言风格的回调函数签名不兼容:非静态成员方法调用时会隐含传入this指针作为第一个参数,不符合CURLOPT_DEBUGFUNCTION要求的int (*)(CURL *, curl_infotype, char *, size_t, void *)签名规则。
解决方案
- 将
trace_data修改为类的静态成员方法,消除隐含的this参数 - 通过
CURLOPT_DEBUGDATA选项将当前类实例的this指针传入回调 - 在静态回调方法中将
userptr参数强转为类实例指针,即可正常访问类的成员变量
修改后的代码示例
类定义部分
class CurlCPPClient { private: // 修改为静态成员方法 static int trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr); curl::curl_easy curl_easy; // 可按需求拆分4个独立缓冲区,分别存储四类内容 std::string req_header; std::string req_data; std::string resp_header; std::string resp_data; public: // 对外暴露缓冲区访问接口即可实现后续读取需求 const std::string& get_req_header() const { return req_header; } const std::string& get_req_data() const { return req_data; } const std::string& get_resp_header() const { return resp_header; } const std::string& get_resp_data() const { return resp_data; } ... };
构造函数部分
CurlCPPClient::CurlCPPClient() { // 传入静态回调函数指针 curl_easy.add<CURLOPT_DEBUGFUNCTION>(&CurlCPPClient::trace_data); // 传入当前实例指针作为回调的userptr参数 curl_easy.add<CURLOPT_DEBUGDATA>(this); // 必须开启VERBOSE配置,否则DEBUGFUNCTION不会被触发 curl_easy.add<CURLOPT_VERBOSE>(1L); }
回调函数实现部分
int CurlCPPClient::trace_data(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr) { // 强转为当前类实例指针 CurlCPPClient* client = static_cast<CurlCPPClient*>(userptr); // 注意:data不一定以\0结尾,必须指定长度构造字符串,避免内存越界 std::string frame_info(data, size); switch(type) { case CURLINFO_HEADER_OUT: client->req_header += frame_info; break; case CURLINFO_DATA_OUT: client->req_data += frame_info; break; case CURLINFO_HEADER_IN: client->resp_header += frame_info; break; case CURLINFO_DATA_IN: client->resp_data += frame_info; break; default: break; } return 0; }
内容的提问来源于stack exchange,提问作者rockstiff
相关产品推荐
相关产品推荐

