libcurl是c++调用web api最成熟跨平台选择;linux用apt安装,macos用homebrew,windows推荐vcpkg;发json post需设curlopt_postfields、content-type头、writecallback,并处理重定向、gzip、ssl验证等细节。

用 C++ 调用 Web API 接口,libcurl 是最成熟、跨平台、可控性最强的选择;它不依赖 Qt 或 Boost 等大型框架,适合嵌入式、服务端或轻量 CLI 工具场景。
怎么引入 libcurl(Windows / Linux / macOS)
不同系统下,libcurl 的获取和链接方式差异明显,直接决定后续能否编译通过:
- Linux(Ubuntu/Debian):
sudo apt install libcurl4-openssl-dev,编译时加-lcurl - macOS:用 Homebrew 安装
brew install curl,头文件在/opt/homebrew/include/curl/(Apple Silicon),链接时加-lcurl,注意可能需指定路径:-L/opt/homebrew/lib - Windows:推荐用 vcpkg:
vcpkg install curl:x64-windows,然后在 CMake 中find_package(CURL REQUIRED);手动链接容易漏ws2_32.lib和wldap32.lib,导致undefined reference to 'curl_easy_init'
怎么发一个标准 JSON POST 请求
多数 Web API 要求 Content-Type: application/json,且请求体是 UTF-8 编码的 JSON 字符串。关键点不在“发出去”,而在“发得对”:
- 必须调用
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_str.c_str()),不能只设 URL 后靠GET拼参 - 必须显式设置
Content-Typeheader:struct curl_slist* headers = nullptr; headers = curl_slist_append(headers, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); -
json_str必须是std::string(非const char*临时字面量),否则curl可能在发送中途读到已释放内存 - 务必检查返回值:
CURLcode res = curl_easy_perform(curl);,res != CURLE_OK时,用curl_easy_strerror(res)查错,而不是只看 HTTP 状态码
#include <curl/curl.h>
#include <string>
#include <iostream><p>size_t WriteCallback(void<em> contents, size_t size, size_t nmemb, void</em> userp) {
((std::string<em>)userp)->append((char</em>)contents, size <em> nmemb);
return size </em> nmemb;
}</p><p>int main() {
CURL* curl;
CURLcode res;
std::string readBuffer;
std::string json = R"({"name":"Alice","age":30})";</p><pre class='brush:php;toolbar:false;'>curl = curl_easy_init();
if (!curl) return -1;
curl_easy_setopt(curl, CURLOPT_URL, "https://httpbin.org/post");
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, json.length());
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << "\n";
} else {
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
std::cout << "HTTP " << http_code << "\n" << readBuffer << "\n";
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return 0;}
立即学习“C++免费学习笔记(深入)”;
为什么 response 返回空或乱码?常见陷阱
不是接口没响应,而是 libcurl 默认不处理重定向、不自动解压、不校验证书——这些都得手动开:
- 遇到 301/302 重定向但没跳转?补上:
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); - 返回 gzip 压缩内容却显示乱码?加:
curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, "");(空字符串表示接受所有编码,libcurl自动解压) - HTTPS 请求失败,报
SSL certificate problem?开发阶段可临时禁用验证:curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);(上线前必须删掉) - 中文字段在 response 里变成
\u4f60\u597d?那是服务器返回了 Unicode 转义,不是libcurl的问题;解析 JSON 时用支持 UTF-8 的库(如nlohmann/json),别用手工substr
真正难的不是写通第一个请求,而是让错误可定位、超时可控制、证书可配置、JSON 可解析、重定向可追溯——这些细节堆起来,才构成一次生产可用的 API 调用。











