Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/233.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 理解BufferStruct+;WriteMemoryCallback_C++_Function_Libcurl - Fatal编程技术网

C++ 理解BufferStruct+;WriteMemoryCallback

C++ 理解BufferStruct+;WriteMemoryCallback,c++,function,libcurl,C++,Function,Libcurl,我找到了这个 他想在这里干什么?特别是乘以这些尺寸? 他试图展示如何将你得到的html代码导出到一个文件中。 为什么有必要(对我来说)编写这样一个复杂的函数? 如果有人能解释或发布一些能帮助我理解这一点的源代码,我将不胜感激:)下面的代码就是“C”方式。。LBCURL是一个C库(它也有C++封装): 这是C的做事方式 C++方式如下: struct BufferStruct { char* buffer; size_t size; }; static size_t Write

我找到了这个

他想在这里干什么?特别是乘以这些尺寸? 他试图展示如何将你得到的html代码导出到一个文件中。 为什么有必要(对我来说)编写这样一个复杂的函数? 如果有人能解释或发布一些能帮助我理解这一点的源代码,我将不胜感激:)

下面的代码就是“C”方式。。LBCURL是一个C库(它也有C++封装):

这是C的做事方式

C++方式如下:

struct BufferStruct
{
    char* buffer;
    size_t size;
};

static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
    size_t realsize = size * nmemb;  //size is the size of the buffer. nmemb is the size of each element of that buffer.
    //Thus  realsize = size * sizeof(each_element).

    //example:  size_t realsize = size * sizeof(char)  or size_t realsize = size * sizeof(wchar_t)
    //Again: size is the buffer size and char or wchar_t is the element size.

    struct BufferStruct* mem = (struct BufferStruct*) data;

    //resize the buffer to hold the old data + the new data.
    mem->buffer = realloc(mem->buffer, mem->size + realsize + 1); 

    if (mem->buffer)
    {
        memcpy(&(mem->buffer[mem->size]), ptr, realsize); //copy the new data into the buffer.
        mem->size += realsize; //update the size of the buffer.
        mem->buffer[mem->size] = 0; //null terminate the buffer/string.
    }
    return realsize;
}

看起来,
BufferStruct
是一种将数据指针和数据大小打包在一起的方法。这是一件好事,因为你当然不想把这些弄糊涂

乘法是取一个成员的
nmemb
,即成员数和
size
,即一个成员的大小,以得到完整的大小。并在realloc中添加一个,为空字符串终止符腾出空间。空字符串终止符只是为了安全。毕竟,curl读取的数据可能和文本文件一样容易成为JPEG图像


这个功能的必要性?它收集curl读取到单个缓冲区中的所有数据。这其实是没有必要的。您可以调用
fwrite
在每次回调时写入文件,而不是将其写入内存的函数。事实上,函数参数的设计几乎与
fwrite

标准库中有几个函数使用元素数x元素大小的概念,而不是简单的字节计数(例如
calloc
)。这是一个与此相同的回调函数。它所做的只是将提供的数据复制到一个动态扩展的内存缓冲区中。参数记录在我假设您正在使用的CURLOPT_WRITEFUNCTION的文档中,尽管您没有这样说。。。您的摘录是一段名为getinmemory.cHello的官方libcurl示例代码,感谢您的回复。我仍然有一个问题:为什么要创建这些函数参数?如果我理解正确,你给curl_easy_setopt函数一个函数指针作为参数,这样它就使用你的write函数而不是你的,对吗?那么,我怎样才能知道我自己的函数在使用curl类时的外观呢?谢谢,我不明白你的问题。这些函数参数是在libcurl回调中定义的:这意味着如果您希望curl使用您的函数,它必须具有这些参数(签名)。您的函数必须看起来像“WriteMemoryCallback”。这是您的自定义函数。
struct BufferStruct
{
    char* buffer;
    size_t size;
};

static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
    size_t realsize = size * nmemb;  //size is the size of the buffer. nmemb is the size of each element of that buffer.
    //Thus  realsize = size * sizeof(each_element).

    //example:  size_t realsize = size * sizeof(char)  or size_t realsize = size * sizeof(wchar_t)
    //Again: size is the buffer size and char or wchar_t is the element size.

    struct BufferStruct* mem = (struct BufferStruct*) data;

    //resize the buffer to hold the old data + the new data.
    mem->buffer = realloc(mem->buffer, mem->size + realsize + 1); 

    if (mem->buffer)
    {
        memcpy(&(mem->buffer[mem->size]), ptr, realsize); //copy the new data into the buffer.
        mem->size += realsize; //update the size of the buffer.
        mem->buffer[mem->size] = 0; //null terminate the buffer/string.
    }
    return realsize;
}
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
    size_t realsize = size * nmemb;

    std::string* mem = reinterpret_cast<std::string*>(data);
    mem->append(static_cast<char*>(data), realsize);

    return realsize;
}
std::string data; //create the std::string..
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); //set the callback.
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &data); //pass the string as the data pointer.