cURL write_callback 不传递用户数据参数

cURL write_callback does not pass userdata argument

我正在尝试从 URL 收集一些数据。如果我没有定义任何 CURLOPT_WRITEFUNCTION and CURLOPT_WRITEDATA I can obviously see the output on console. Then I tried to write that data to memory by copiying the example code,但是我的回调函数的 userdata 参数返回 NULL 并且我在线上遇到以下异常:

char* ptr = (char*)realloc(mem->memory, mem->size + realsize + 1);

Exception thrown: read access violation.
mem was nullptr.

我是不是做错了什么?

这是我的代码:

struct MemoryStruct {
    char* memory;
    size_t size;
};

//-----------------
// Curl's callback
//-----------------
size_t CurlWrapper::curl_cb(char* data, size_t size, size_t nmemb, void* response)
{
    size_t realsize = size * nmemb;
    std::cout << "CALLBACK CALLED" << std::endl;

    MemoryStruct* mem = (struct MemoryStruct*)response;
    char* ptr = (char*)realloc(mem->memory, mem->size + realsize + 1);
    if (!ptr) {
        /* out of memory! */
        printf("not enough memory (realloc returned NULL)\n");
        return 0;
    }

    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), data, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;

    return realsize;
}

//--------------------
// Do the curl
//--------------------
void CurlWrapper::curl_api(
      const std::string& url,
            std::string& str_result)
{

    MemoryStruct chunk;

    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlWrapper::curl_cb);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);
        // TODO: enable ssh certificate
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); // true
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false); // 2
        curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "zlib");

        auto res = curl_easy_perform(curl);

        /* Check for errors */
        if (res != CURLE_OK) {
            // nothing
            std::cout << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        }
    }
}

libcurl 版本:7.82.0

由于 libcurl 是一个 C 库,它对 C++ 成员函数或对象一无所知。您可以相对轻松地克服这种“限制”,例如使用传递指向 class.

的指针的静态成员函数

参见此示例(来自 everything curl 书)。

// f is the pointer to your object.
static size_t YourClass::func(void *buffer, size_t sz, size_t n, void *f)
{
  // Call non-static member function.
  static_cast<YourClass*>(f)->nonStaticFunction();
}

// This is how you pass pointer to the static function:
curl_easy_setopt(hcurl, CURLOPT_WRITEFUNCTION, YourClass::func);
curl_easy_setopt(hcurl, CURLOPT_WRITEDATA, this);