VC++ 中 JSON 数据的发送与接收:完整指南
在 Windows 应用程序开发中,VC++(Visual C++)作为经典开发工具,常需与 Web 服务或现代应用程序进行数据交互,JSON(JavaScript Object Notation)因其轻量、易读、跨语言特性,成为主流的数据交换格式,本文将详细介绍如何在 VC++ 中实现 JSON 数据的发送与接收,涵盖基础概念、常用库选择、具体代码示例及常见问题解决。
JSON 数据交互基础:发送与接收的核心流程
JSON 数据的交互本质是序列化(Serialization)与反序列化(Deserialization)的过程:
- 发送(客户端→服务端):将 C++ 数据结构(如类、结构体、STL 容器)序列化为 JSON 字符串,通过 HTTP 请求(如 POST、PUT)发送到服务端。
- 接收(服务端→客户端):从 HTTP 响应中获取 JSON 字符串,反序列化为 C++ 数据结构,供程序逻辑使用。
关键步骤概览
- 选择 JSON 库:VC++ 无内置 JSON 支持,需借助第三方库(如 nlohmann/json、RapidJSON、JsonCpp)。
- 数据准备:定义 C++ 数据结构(类/结构体),与 JSON 字段对应。
- 序列化:将 C++ 对象转为 JSON 字符串。
- 网络请求:通过 HTTP 客户端(如 WinINet、libcurl、C++ REST SDK)发送 JSON 数据。
- 接收响应:获取服务端返回的 JSON 字符串。
- 反序列化:将 JSON 字符串解析为 C++ 数据结构。
选择合适的 JSON 库
VC++ 生态中常用的 JSON 库各有优劣,需根据项目需求(如性能、易用性、许可协议)选择:
| 库名 | 特点 | 适用场景 |
|---|---|---|
| nlohmann/json | 纯头文件实现(只需包含 json.hpp),语法简洁,支持现代 C++ 特性(如 STL 容器、lambda) |
中小型项目,追求开发效率 |
| RapidJSON | 高性能(C 风格 API,零拷贝设计),内存占用低 | 对性能要求高的场景(如游戏) |
| JsonCpp | 跨平台,支持 DOM 和 SAX 解析,API 较友好 | 需要兼容旧版 C++ 的项目 |
推荐选择:nlohmann/json(本文以该库为例,因其易用性和现代 C++ 风格,适合大多数场景)。
安装 nlohmann/json
- 下载源码:从 GitHub Releases 下载
json.hpp文件。 - 将
json.hpp放入项目目录(如include文件夹),并在代码中包含:#include "json.hpp" using json = nlohmann::json;
JSON 数据发送:从 C++ 对象到 HTTP 请求
定义 C++ 数据结构
假设需发送一个用户信息对象,包含姓名、年龄、邮箱和地址列表,定义如下:
#include <string>
#include <vector>
struct Address {
std::string city;
std::string street;
int zipCode;
};
struct UserInfo {
std::string name;
int age;
std::string email;
std::vector<Address> addresses;
};
序列化为 JSON 字符串
使用 nlohmann/json 将 UserInfo 对象转为 JSON 字符串:
#include <iostream>
UserInfo createUserInfo() {
UserInfo user;
user.name = "张三";
user.age = 30;
user.email = "zhangsan@example.com";
Address addr1{"北京", "朝阳区建国路88号", 100022};
Address addr2{"上海", "浦东新区陆家嘴环路1000号", 200120};
user.addresses = {addr1, addr2};
return user;
}
std::string serializeToJson(const UserInfo& user) {
json j;
j["name"] = user.name;
j["age"] = user.age;
j["email"] = user.email;
json addressesJson = json::array();
for (const auto& addr : user.addresses) {
json addrJson;
addrJson["city"] = addr.city;
addrJson["street"] = addr.street;
addrJson["zipCode"] = addr.zipCode;
addressesJson.push_back(addrJson);
}
j["addresses"] = addressesJson;
return j.dump(); // dump() 将 json 对象转为字符串,默认格式化输出
}
int main() {
UserInfo user = createUserInfo();
std::string jsonString = serializeToJson(user);
std::cout << "JSON 字符串:\n" << jsonString << std::endl;
return 0;
}
输出:
{
"name": "张三",
"age": 30,
"email": "zhangsan@example.com",
"addresses": [
{
"city": "北京",
"street": "朝阳区建国路88号",
"zipCode": 100022
},
{
"city": "上海",
"street": "浦东新区陆家嘴环路1000号",
"zipCode": 200120
}
]
}
发送 JSON 数据(HTTP 请求)
VC++ 中可通过多种方式发送 HTTP 请求,这里推荐 C++ REST SDK(Casablanca)(微软官方开发,支持异步请求,易用性高)。
安装 C++ REST SDK
- 下载 SDK:从 GitHub Releases 下载预编译库(如
vcpkg安装:vcpkg install cpprestsdk)。 - 配置项目:包含头文件路径和库文件路径(如
include/cpprestsdk和lib/x64)。
发送 POST 请求(带 JSON 数据)
#include <cpprest/http_client.h>
#include <cpprest/filestream.h>
using namespace web;
using namespace web::http;
using namespace web::http::client;
using namespace utility;
void sendJsonData(const std::string& jsonString) {
// 创建 HTTP 客户端(目标服务端 URL)
http_client client(U("http://example.com/api/user")); // U() 表示宽字符串
// 构造 HTTP 请求
http_request request(methods::POST);
request.headers().add(U("Content-Type"), U("application/json")); // 设置 Content-Type
// 将 JSON 字符串作为请求体
request.set_body(jsonString);
// 发送请求并获取响应
client.request(request)
.then([](http_response response) {
std::cout << "状态码: " << response.status_code() << std::endl;
return response.extract_string();
})
.then([](string_t body) {
std::cout << "服务端响应: " << body << std::endl;
})
.wait(); // 阻塞等待异步请求完成
}
int main() {
UserInfo user = createUserInfo();
std::string jsonString = serializeToJson(user);
sendJsonData(jsonString);
return 0;
}
说明:
U("...")表示utility::string_t类型,支持宽字符(避免编码问题)。application/json是 JSON 数据的标准Content-Type。- 异步请求通过
then()链式调用,wait()阻塞等待结果(实际项目中建议用async/await或回调处理)。
JSON 数据接收:从 HTTP 响应到 C++ 对象
接收 HTTP 响应(JSON 字符串)
假设服务端返回的 JSON 响应如下:
{
"success": true,
"data": {
"userId": 1001,
"userName": "李四",
"roles": ["admin", "editor"]
},
"message": "查询成功"
}
反序列化为 C++ 对象
定义对应的 C++ 结构体:
struct ResponseData {
int userId;
std::string userName;
std::vector<std::string> roles;
};
struct ApiResponse {
bool success;
ResponseData data;
std::string message;
};
使用 nlohmann/json 解析 JSON 字符串:
ApiResponse parseJsonResponse(const std::string& jsonString) {
json j = json::parse(jsonString); // 解析 JSON 字符串
ApiResponse response;
response.success = j["success"].get<bool>();
response.message = j["message"].get<std::


还没有评论,来说两句吧...