Rapidjson中stringRef,SetString的真正含义

 

\u00000\u0004T_\u0000\u0000E html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
 

 

使用rapidjson时出现以上问题,1.不是完整的内容,2.多次转义\


bid.AddMember("adm", rapidjson::StringRef(html_snippet.c_str(),html_snippet.size()), allocator);


stringRef(html_snippet.c_str())一开始以为可能可能是字符串结束标志问题,这种方式会调动C的strlen去查找\0判断字符串结束,而指定字符串长度的size后仍然会有\u00000的乱码出现.

使用另一种方式,未出现此种问题:
Value str_val;
str_val.SetString(html_snippet.c_str(),html_snippet.length(),allocator);
bid.AddMember("adm", str_val, allocator);

等价的方式:ringRef(html_snippet.c_str(),Value().SetString(html_snippet.c_str(),allocator).Move(),allocator)

回去仔细查看手册对比源码,这两种方式的差异是StringRef是引用转移,也就是把指针指向了真正内容所在的内存区域。而第二种方式是值copy的方式,会分配内存把字符串复制一份副本。所以问题的根源是html_snippet 是临时局部变量,在document对象序列成json string是html_snippet局部变量已被析构,故转移的方式指向的内存区域是未知的,导致了\00000的出现。

 

 

ccache arm-linux-gnueabihf-9.1.0-g++ -> <main> mainthread.o /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/riscoapi/risco_api.cpp: In lambda function: /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/riscoapi/risco_api.cpp:1488:56: error: no matching function for call to ‘AutoReply::AddMember(const ApiRangeNode<std::__cxx11::basic_string<char> >&, std::string&)’ 1488 | rep->AddMember(ndFilepath, m_pRcord->m_filepath); | ^ In file included from /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/interface/http_intf/include/httpapi_intf.h:6, from /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/riscoapi/risco_api.cpp:6: /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/interface/http_intf/include/autoreply.h:115:10: note: candidate: ‘template<class T, int n> bool AutoReply::AddMember(ApiNode<T, n>&, float, rapidjson::Value*)’ 115 | bool AddMember(ApiNode<T, n> &node, float value, hl::json::Value *parent = NULL); | ^~~~~~~~~ /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/interface/http_intf/include/autoreply.h:115:10: note: template argument deduction/substitution failed: /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/riscoapi/risco_api.cpp:1488:56: note: types ‘ApiNode<T, n>’ and ‘const ApiRangeNode<std::__cxx11::basic_string<char> >’ have incompatible cv-qualifiers 1488 | rep->AddMember(ndFilepath, m_pRcord->m_filepath); | ^ In file included from /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/interface/http_intf/include/httpapi_intf.h:6, from /home/xiaoshiyin/source/custom_cloud/RISCO_v1_C1.2/main/../module/network/riscoapi/risco_api.cpp:6: /home/xiaoshiyin/source/custom_
03-20
<think>好的,我现在需要解决用户提到的C++编译错误,具体是关于AutoReply::AddMember函数模板类型不匹配的问题。用户提到错误发生在ApiRangeNode、string和rapidjson相关的代码中。首先,我得分析可能的原因。 首先,考虑函数模板的参数类型是否匹配。AddMember可能是rapidjson库中的方法,用于向JSON文档中添加成员。rapidjson的AddMember通常需要名称和值参数,且名称应该是rapidjson::Value类型的,而值可以是多种类型,但必须正确转换。 用户可能在调用AddMember时,直接传递了std::string或const char*作为名称,而rapidjson要求使用StringRef或显式创建Value。例如,正确的用法可能是使用MakeString或StringRef来包装字符串。 接下来,检查参数类型是否完全匹配。如果ApiRangeNode是自定义类型,可能需要转换为rapidjson识别的类型,或者使用适配器。此外,检查是否遗漏了文档的分配器(Allocator),因为rapidjson的操作通常需要传递allocator。 另外,考虑模板参数是否显式指定正确。如果AddMember是模板函数,可能需要显式指定类型,或者确保传入的参数类型能被正确推导。 用户提供的引用中提到pRep是一个需要手动管理内存的API响应处理器,可能涉及对象生命周期的问题,但当前错误更可能是类型不匹配导致的。 综合这些可能性,解决方案可能包括:使用StringRef包装字符串,确保使用正确的Value类型,传递allocator,以及检查自定义类型转换是否正确。需要具体查看代码中的AddMember调用,指出哪里参数类型不匹配,并给出修改建议。</think>针对AutoReply::AddMember函数模板类型不匹配的编译错误,以下是分步解决方案: 1. **检查函数原型** 确保调用的函数原型与声明一致。rapidjson中标准AddMember函数有两种形式: ```cpp Value& AddMember(const Ch* name, Value& value, Allocator& allocator) Value& AddMember(Value& name, Value& value, Allocator& allocator) ``` 2. **字符串参数处理** 当使用std::string或char数组作为键名时,必须转换为rapidjson::StringRef: ```cpp // 错误示例 doc.AddMember("key", value, alloc); // 正确写法 doc.AddMember(rapidjson::StringRef("key"), value, alloc); // 或使用C风格字符串自动转换 doc.AddMember("key", rapidjson::Value().SetString("value", alloc), alloc); ``` 3. **值参数处理** 确保值参数已正确构造为rapidjson::Value类型: ```cpp // 错误示例(直接使用int) doc.AddMember("age", 25, alloc); // 正确写法 doc.AddMember("age", rapidjson::Value(25), alloc); ``` 4. **处理自定义类型** 如果涉及ApiRangeNode类型,需要实现类型转换: ```cpp // 在ApiRangeNode类中定义转换操作符 operator rapidjson::Value() const { rapidjson::Value val; val.SetObject(); val.AddMember("start", start_, allocator_); val.AddMember("end", end_, allocator_); return val; } ``` 5. **分配器传递** 所有Value创建操作必须显式传递allocator: ```cpp rapidjson::Document doc; auto& alloc = doc.GetAllocator(); doc.AddMember("config", rapidjson::Value(configValue).Move(), alloc); ``` 6. **处理字符串编码** 当使用Unicode字符时,必须指定字符串长度和编码: ```cpp std::wstring unicodeStr = L"Unicode内容"; doc.AddMember("unicode", rapidjson::Value().SetString( reinterpret_cast<const char*>(unicodeStr.c_str()), unicodeStr.size() * sizeof(wchar_t), alloc ), alloc ); ``` **典型错误修正示例:** ```cpp // 原始错误代码 AutoReply reply; reply.AddMember(ApiRangeNode(1,100), "testValue"); // 修正后代码 rapidjson::Document doc; auto& alloc = doc.GetAllocator(); rapidjson::Value name; name.SetString( ApiRangeNode(1,100).ToString().c_str(), alloc ); rapidjson::Value value; value.SetString("testValue", alloc); doc.AddMember(name, value, alloc); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值