gpt4 book ai didi

c++ - libcurl C++ 的内存访问错误

转载 作者:行者123 更新时间:2023-11-30 05:30:09 30 4
gpt4 key购买 nike

我正在尝试制作一个非常简单的程序来获取用户请求(控制台)并将此请求发送到 header (libcurl) 中的网站,然后获取响应 header 。

所以我有2个类(实际上我有很多类但是对于这里的问题我会简化)

我的 main.cpp 收到请求并将其发送到我的服务。

这是我的服务 Fuzzer.h :

#ifndef FUZZER_H
#define FUZZER_H

#include <string>

using namespace std;

namespace furez
{
class Fuzzer {
private:
string url;
string response;
static size_t writeH_static(void *, size_t, size_t, void *);

public:
Fuzzer(string);
virtual ~Fuzzer();
string sendRequest(string);
size_t writeH(void *, size_t, size_t);
};

}

#endif

这是我的 Fuzzer.cpp:

#include <string>
#include <curl/curl.h>
#include <iostream>

#include "Fuzzer.h"

namespace furez
{
Fuzzer::Fuzzer(std::string u)
{
this->url = u;
}

Fuzzer::~Fuzzer(){}

string Fuzzer::sendRequest(std::string request)
{
CURL *curl;
CURLcode res;

static const char *headerfilename = "head.out";
static const char *bodyfilename = "body.out";

curl = curl_easy_init();
if (curl) {
struct curl_slist *chunk = NULL;

chunk = curl_slist_append(chunk, "Accept:");
chunk = curl_slist_append(chunk, "Another: yes");
chunk = curl_slist_append(chunk, "Host: example.com");
chunk = curl_slist_append(chunk, "X-silly-header;");

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Fuzzer::writeH);

Fuzzer instance(request);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &instance);

curl_easy_setopt(curl, CURLOPT_URL, "localhost");

res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
}

curl_easy_cleanup(curl);
curl_slist_free_all(chunk);
}

return request;
}

size_t Fuzzer::writeH_static(void *ptr, size_t size, size_t nmemb, void *stream)
{
return ((Fuzzer*)stream)->writeH(ptr, size, nmemb);
}

size_t Fuzzer::writeH(void *ptr, size_t size, size_t nmemb)
{
//std::string str = (CHAR *)ptr;
//std::string str2("Server:");

//if (str.find(str2) != string::npos) {
//this->response = str;
//}

size_t realsize = size * nmemb;
return realsize;
}
}

但是当我尝试执行此操作时,我遇到了内存错误。正因为如此:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Fuzzer::writeH);

我正在为我的项目使用 libcurl。我知道这是一个 C 库,也许这是问题所在?

为了帮助我,我遵循了这些说明: libcurl callbacks w/c++ class members

还有这个: curl WRITEFUNCTION and classes我在 Windows 7 上安装了 Visual Studio 2013。

(PS:当我把没有 &Fuzzer::writeH 和静态函数的代码放在 main.cpp 中时,它可以正常工作。)

最佳答案

我认为问题出在这里:

curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &Fuzzer::writeH);

正如您正确指出的那样,libcurl 是一个 C 库,但是您向函数 curl_easy_setopt 传递了一个指向成员函数的指针。现在,函数指针和指向类成员的指针是不同的类型,所以,你不能那样做。我知道的唯一解决方案是使用蹦床调用

  • 创建一个普通函数(非您类的成员),您将在 curl_easy_setopt() 中将其注册为回调
  • 让蹦床回调成为你类(class)的 friend (这样她就可以在需要时访问私有(private)成员)
  • 传递给回调的userdata参数应该是指向你的类的指针
  • 在 trampoline 回调中,您会将指针投回您的类并调用所需的成员函数

举个例子:

extern "C" size_t trampolineCallback( char * i_buffer, size_t i_size, size_t i_nitems, void * i_userdata );

在你的类实现中你将有类似的东西:

curl_easy_setopt( m_curlHndlPtr, CURLOPT_HEADERDATA, (void*) this );
curl_easy_setopt( m_curlHndlPtr, CURLOPT_HEADERFUNCTION, trampolineCallback );

您的蹦床实现将如下所示:

size_t trampolineCallback(char *i_buffer, size_t i_size, size_t i_nitems, void *i_userdata)
{
MyObj * object = (MyObj*) i_userdata;
object->myMemberFunc( i_buffer,i_size, i_nitems );
return (i_size * i_nitems);
}

关于c++ - libcurl C++ 的内存访问错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36116041/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com