强者的自我修养免安装绿色中文版
4.29G · 2025-11-02
// 1. Document - JSON文档的根(类似一个JSON对象容器)
rapidjson::Document document;
// 2. Value - JSON值(可以是对象、数组、字符串、数字等)
rapidjson::Value value;
// 3. Allocator - 内存分配器(RapidJSON需要它来分配内存)
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
kNullType // null
kFalseType // false
kTrueType // true
kObjectType // { "key": value }
kArrayType // [ value, value, ... ]
kStringType // "string"
kNumberType // 123, 3.14
// 第1步:创建文档
rapidjson::Document document;
// 第2步:初始化为对象类型
document.SetObject();
// 第3步:获取分配器
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
// 第4步:添加键值对
document.AddMember("name", "John", allocator);
document.AddMember("age", 30, allocator);
document.AddMember("active", true, allocator);
// 结果: {"name":"John","age":30,"active":true}
std::string myString = "Hello World";
// 错误方式(会导致内存问题)
// document.AddMember("msg", myString, allocator);
// 正确方式1:使用SetString
rapidjson::Value stringValue;
stringValue.SetString(myString.c_str(), myString.size(), allocator);
document.AddMember("msg", stringValue, allocator);
// 正确方式2:简洁写法
document.AddMember(
"msg",
rapidjson::Value().SetString(myString.c_str(), myString.size(), allocator),
allocator
);
// 创建嵌套对象
rapidjson::Value personObj(rapidjson::kObjectType);
personObj.AddMember("firstName", "John", allocator);
personObj.AddMember("lastName", "Doe", allocator);
// 添加到主文档
document.AddMember("person", personObj, allocator);
/* 结果:
{
"person": {
"firstName": "John",
"lastName": "Doe"
}
}
*/
// 创建数组
rapidjson::Value arrayValue(rapidjson::kArrayType);
// 添加元素
arrayValue.PushBack(10, allocator);
arrayValue.PushBack(20, allocator);
arrayValue.PushBack(30, allocator);
// 添加到文档
document.AddMember("numbers", arrayValue, allocator);
/* 结果:
{
"numbers": [10, 20, 30]
}
*/
rapidjson::Value itemsArray(rapidjson::kArrayType);
// 创建第一个对象
rapidjson::Value item1(rapidjson::kObjectType);
item1.AddMember("id", 1, allocator);
item1.AddMember("name", "Item 1", allocator);
itemsArray.PushBack(item1, allocator);
// 创建第二个对象
rapidjson::Value item2(rapidjson::kObjectType);
item2.AddMember("id", 2, allocator);
item2.AddMember("name", "Item 2", allocator);
itemsArray.PushBack(item2, allocator);
document.AddMember("items", itemsArray, allocator);
/* 结果:
{
"items": [
{"id": 1, "name": "Item 1"},
{"id": 2, "name": "Item 2"}
]
}
*/
// 基本用法
document.AddMember("key", value, allocator);
// 支持的数据类型
document.AddMember("string", "value", allocator); // 字符串
document.AddMember("int", 42, allocator); // 整数
document.AddMember("double", 3.14, allocator); // 浮点数
document.AddMember("bool", true, allocator); // 布尔值
document.AddMember("null", rapidjson::Value(), allocator); // null值
if (document.HasMember("name")) {
std::cout << "name exists" << std::endl;
}
// 安全的获取值
if (document.HasMember("name") && document["name"].IsString()) {
std::string name = document["name"].GetString();
}
document.RemoveMember("oldField");
// 方式1:直接访问
std::string name = document["name"].GetString();
// 方式2:安全访问(检查存在性)
if (document.HasMember("name") && document["name"].IsString()) {
std::string name = document["name"].GetString();
}
int age = document["age"].GetInt(); // 整数
double salary = document["salary"].GetDouble(); // 浮点数
bool active = document["active"].GetBool();
// JSON: {"person": {"name": "John"}}
std::string personName = document["person"]["name"].GetString();
// 方式1:通过GetArray()
const rapidjson::Value& array = document["numbers"].GetArray();
for (const auto& item : array) {
int num = item.GetInt();
std::cout << num << std::endl;
}
// 方式2:直接遍历
for (const auto& item : document["numbers"].GetArray()) {
std::cout << item.GetInt() << std::endl;
}
if (value.IsString()) { std::cout << "是字符串" << std::endl; }
if (value.IsInt()) { std::cout << "是整数" << std::endl; }
if (value.IsDouble()) { std::cout << "是浮点数" << std::endl; }
if (value.IsBool()) { std::cout << "是布尔值" << std::endl; }
if (value.IsArray()) { std::cout << "是数组" << std::endl; }
if (value.IsObject()) { std::cout << "是对象" << std::endl; }
if (value.IsNull()) { std::cout << "是null" << std::endl; }
// 步骤1:创建StringBuffer来存储结果
rapidjson::StringBuffer buffer;
// 步骤2:创建Writer并写入文档
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
document.Accept(writer);
// 步骤3:获取JSON字符串
std::string jsonString = buffer.GetString();
std::cout << jsonString << std::endl;
std::string jsonString = R"({"name": "John", "age": 30})";
// 步骤1:创建新文档
rapidjson::Document doc;
// 步骤2:解析JSON字符串
doc.Parse(jsonString.c_str());
// 步骤3:检查是否解析成功
if (doc.HasParseError()) {
std::cerr << "Parse error!" << std::endl;
return;
}
// 步骤4:访问解析后的数据
std::string name = doc["name"].GetString();
int age = doc["age"].GetInt();
现在让我为你详细讲解你的 setImageList() 函数:
void setImageList(std::string deviceId, std::list<image> list) {
using namespace rapidjson;
// ========== 第1步:创建文档 ==========
Document document;
document.SetObject();
// ========== 第2步:设置消息头 ==========
// address: 指定接收端处理该消息的处理器类型为 "imageplayer"
document.AddMember("address", "imageplayer", document.GetAllocator());
// action: 指定执行什么操作为 "setImageList"
document.AddMember("action", "setImageList", document.GetAllocator());
// ========== 第3步:创建数据对象 ==========
Value data(kObjectType);
// 添加目标设备ID
data.AddMember(
"to",
rapidjson::Value().SetString(
deviceId.c_str(),
deviceId.size(),
document.GetAllocator()
),
document.GetAllocator()
);
// ========== 第4步:创建图片列表数组 ==========
Value listValue(kArrayType);
// 遍历输入的图片列表
for (auto it : list) {
// 为每个图片创建对象
Value item(kObjectType);
// 添加图片ID
item.AddMember(
"id",
rapidjson::Value().SetString(
it.id.c_str(),
it.id.size(),
document.GetAllocator()
),
document.GetAllocator()
);
// 添加图片URL(文件路径)
item.AddMember(
"url",
rapidjson::Value().SetString(
it.url.c_str(),
it.url.size(),
document.GetAllocator()
),
document.GetAllocator()
);
// 添加图片名称
item.AddMember(
"name",
rapidjson::Value().SetString(
it.name.c_str(),
it.url.size(), // ️ 注意:这里可能是个BUG,应该是 it.name.size()
document.GetAllocator()
),
document.GetAllocator()
);
// 将该图片对象添加到数组
listValue.PushBack(item, document.GetAllocator());
}
// ========== 第5步:将列表添加到数据对象 ==========
data.AddMember("list", listValue, document.GetAllocator());
// ========== 第6步:将数据添加到文档 ==========
document.AddMember("data", data, document.GetAllocator());
// ========== 第7步:序列化为JSON字符串 ==========
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
document.Accept(writer);
std::string str = buffer.GetString();
// ========== 第8步:发送消息 ==========
HHCastServerCore::getInstance()->sendMessage(str);
}
{
"address": "imageplayer",
"action": "setImageList",
"data": {
"to": "device_123",
"list": [
{
"id": "img_001",
"url": "C:/images/photo1.jpg",
"name": "photo1.jpg"
},
{
"id": "img_002",
"url": "C:/images/photo2.png",
"name": "photo2.png"
}
]
}
}
// 问题:name字段的大小使用了错误的值
item.AddMember(
"name",
rapidjson::Value().SetString(
it.name.c_str(),
it.url.size(), // ️ 应该是 it.name.size()
document.GetAllocator()
),
document.GetAllocator()
);
// 修正后:
item.AddMember(
"name",
rapidjson::Value().SetString(
it.name.c_str(),
it.name.size(), // 使用正确的size
document.GetAllocator()
),
document.GetAllocator()
);
| 操作 | 代码示例 | 说明 |
|---|---|---|
| 创建文档 | Document doc; doc.SetObject(); | 初始化空对象 |
| 添加键值对 | doc.AddMember("key", value, allocator); | 添加成员 |
| 获取字符串 | doc["key"].GetString() | 读取字符串值 |
| 获取整数 | doc["key"].GetInt() | 读取整数值 |
| 创建数组 | Value arr(kArrayType); | 创建空数组 |
| 添加到数组 | arr.PushBack(value, allocator); | 向数组添加元素 |
| 遍历数组 | for(auto& item : doc["arr"].GetArray()) | 循环遍历 |
| 序列化 | StringBuffer buf; Writer w(buf); doc.Accept(w); | 转JSON字符串 |
| 反序列化 | Document doc; doc.Parse(str.c_str()); | 从字符串解析 |
| 检查成员 | doc.HasMember("key") | 检查键是否存在 |
希望这能帮助你理解 RapidJSON!有任何疑问欢迎继续提问。