我从他在网上找到的朋友那里得到了一个功能。问题是,我们都不了解它是如何工作的。它将网页的内容复制到字符串。
我们正在使用cURL连接到php页面。 有问题的功能是:
std::string contents;
size_t handle_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
int numbytes = size*nmemb;
char lastchar = *((char *) ptr + numbytes - 1);
*((char *) ptr + numbytes - 1) = '\0';
contents.append((char *)ptr);
contents.append(1,lastchar);
*((char *) ptr + numbytes - 1) = lastchar; // Might not be necessary.
return size*nmemb;
}
在这个函数中调用它:
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,handle_data);
对其工作方式的任何解释都会很棒。 欢呼声。
答案 0 :(得分:2)
我认为这是正确的:
std::string contents;
size_t handle_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
// The number of bytes to transfer is simply the
// number of elements (nmemb) times the size of
// each element (size).
int numbytes = size*nmemb;
// Remember the last character of the data we'll
// be appending to 'contents', because we're about
// to overwrite it with a zero C-string nul terminator.
char lastchar = *((char *) ptr + numbytes - 1);
// Overwrite the last character of ptr's data block
// with zero, which is a C-string's nul-terminator.
*((char *) ptr + numbytes - 1) = '\0';
// Append the C-string which begins at 'ptr' to
// 'contents'.
contents.append((char *)ptr);
// Now tack on the last character that we remembered above.
contents.append(1,lastchar);
// Restore the original data buffer's last character
// in case the caller expects it to still be the same.
*((char *) ptr + numbytes - 1) = lastchar; // Might not be necessary.
// Return the number of bytes that were appended
// to 'contents'.
return size*nmemb;
}
说了这么多,我不确定为什么handle_data()的全部内容不仅仅是这样:
size_t handle_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
contents.append((char*)ptr, size*nmemb);
return size*nmemb;
}
...我认为只会更正确地完成相同的事情,因为如果'ptr'中的缓冲区包含嵌入的空字符,则发布的版本将提前停止。 (当然,这可能不是这个功能的用例。)
答案 1 :(得分:1)
如果我必须描述它是如何运作的,我会说:“不是特别好”。
int numbytes = size*nmemb;
这会计算缓冲区的大小 - 项目数*每个项目的大小。
char lastchar = *((char *) ptr + numbytes - 1);
这会保存缓冲区中的最后一个字符供以后使用。
*((char *) ptr + numbytes - 1) = '\0';
这会在缓冲区中添加一个NUL终结符,覆盖当前最后一个字符(这就是前面保存它的原因)。
contents.append((char *)ptr);
这会将(截断的)缓冲区附加到字符串。
contents.append(1,lastchar);
这会将保存的最后一个字符添加到字符串中。
*((char *) ptr + numbytes - 1) = lastchar; // Might not be necessary.
这会将最后一个字符恢复到缓冲区中。
return size*nmemb;
这将返回缓冲区大小。
我想我应该解释为什么我说这不起作用。并不是最终结果似乎是错误的,而是因为缓冲区中最后一个字符的所有回转都是完全没有必要的。您可以只指定要附加到字符串的数量,而不是NUL终止缓冲区:
size_t numbytes = size * nmemb;
contents.append((char *)ptr, numbytes);
return numbytes;
...或者,如果您更喜欢类似迭代器的用法:
size_t numbytes = size * nmemb;
char *p = (char *)ptr;
contents.append(p, p+numbytes);
return numbytes;
我猜你如果找到这样的话,你就不必发表一个关于它如何运作的问题。