具有cURL + JSON库的C ++ POST请求

zer*_*r02 2 c++ json curl c++11

我想POST使用发送请求cURL。我正在使用这个(github:nlohmann / json)库来处理我的JSON对象创建。我收到了HTTP 200 Response,但未POST附加数据。

打电话时,std::cout<< json_data.dump() << std::endl; 我收到格式良好的JSON

{
    "a": [
        {
            "c": "0",
            "d": "0",
            "e": "0",
            "f": "0",
            "g": "1506961983",
            "h": "1506961986",
            "i": "3"
        },
        {
            "c": "1",
            "d": "2",
            "e": "1",
            "f": "1",
            "g": "1506961987",
            "h": "1506961991",
            "i": "4"
        }
    ],
    "b": "test"
}
Run Code Online (Sandbox Code Playgroud)

我用它来附加我的数据。

   struct curl_slist *headers=NULL; 
   headers = curl_slist_append(headers, "Accept: application/json");  
   headers = curl_slist_append(headers, "Content-Type: application/json");
   headers = curl_slist_append(headers, "charsets: utf-8"); 
   curl_easy_setopt(curl, CURLOPT_POSTFIELDS,json_data.dump().c_str());
Run Code Online (Sandbox Code Playgroud)

文档curl_easy_setopt文档

如果我查看我的AWS日志。它说:

{
  "format": "json",
  "payload": 5,
  "qos": 0,
  "timestamp": 1506961394810,
  "topic": "test_topic"
}
Run Code Online (Sandbox Code Playgroud)

为什么显示5而不是我的JSON对象的值?

如果有人知道原因,谢谢您的帮助。

Rem*_*eau 5

在这行上:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data.dump().c_str());
Run Code Online (Sandbox Code Playgroud)

返回的字符串对象dump()是临时的,并且在curl_easy_setopt()退出时销毁,因此留下CURLOPT_POSTFIELDS一个悬挂的指针,当libCURL尝试发布该指针时,该指针可能或可能仍未指向内存中的JSON数据。

根据CURLOPT_POSTFIELDS文档

指向的数据不会由库复制:因此,调用应用程序必须保留该数据,直到关联的传输完成为止。可以通过设置CURLOPT_COPYPOSTFIELDS选项来更改此行为(因此libcurl确实会复制数据)。

因此,您需要:

  • 更改CURLOPT_POSTFIELDSCURLOPT_COPYPOSTFIELDS

    curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, json_data.dump().c_str());
    
    Run Code Online (Sandbox Code Playgroud)
  • 将结果保存json_data.dump()到在curl_easy_perform()退出之前不会超出范围的局部变量:

    std::string json = json_data.dump();
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
    ...
    
    Run Code Online (Sandbox Code Playgroud)