代理可以成功取回 HTML,却在把图像复制进 C++ 缓冲区时将其损坏。在改动代理协议之前,请先检查接收回调以及作为其上下文传入的对象。

CURLOPT_WRITEDATA 提供一个指向写入回调的指针。如果没有自定义回调,libcurl 的默认写入器期望收到一个 FILE *。像 &response 这样的地址(其中 response 是 std::string)只有在你的回调把该上下文转换回预期类型时才有意义。

static size_t receive(char* data, size_t size,
                      size_t count, void* context) {
    const size_t bytes = size * count;
    auto* body = static_cast<std::string*>(context);
    try {
        body->append(data, bytes);
    } catch (...) {
        return 0;
    }
    return bytes;
}

把这两半都注册到用于传输的简易句柄上:

std::string response;
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);

append 调用使用实际交付的字节数。回调数据不以空字符结尾,图像也可能包含零字节;用 strlen 测量会丢掉正文的一部分。一次响应还可能通过许多大小不同的回调调用分批到达。

返回已消费的字节数即接受该分片。返回不同的数值会以写入错误中止传输。异常保护可避免分配失败越过 C 回调边界向外传播;调用方仍须先检查传输结果,再把 response 当作完整文件。

让该字符串存活到传输结束。如果随后有异步套接字写入转发其内容,也要让这些字节存活到该写入完成。对于较大的响应,采用有界的流式安排比累积整个正文更可取。

相关文章