RapidJSON 在转换为字符串时产生不一致的结果

rapidjson producing inconsistent results when converting to string

本文关键字:不一致 结果 转换 字符串 RapidJSON      更新时间:2023-10-16

我目前有一个正在使用的JSON序列化程序类。它适用于我正在处理的一些实验性代码。此代码使用 cpprestsdk。序列化设置为使用 rapidjson 或 cpprestsdk 的 json。

例如,类的虚函数如下所示:

virtual void toJson(rapidjson::Document& json) const =0;
virtual void toJson(web::json::value& json) const =0;
virtual void fromJson(const rapidjson::Value& json) =0;
virtual void fromJson(const web::json::value& json) =0;

我可以从 JSON 转换没有问题。我目前正在将类对象转换为 JSON,然后将其作为字符串导出到文件。我发现使用rapidjson,我得到的结果是可变的。

在某些导出中,我看到这样的片段:

"base": {
"nameu0000refere": "base",

在其他运行中,我看到这样的片段:

"base": {
"name": "base",

这适用于连续运行,不更改代码。

这些字段实际上是全局定义的const char *如下所示:

const char *kSymbolKeyName = "name";
const char *kSymbolKeyReferenceName = "referenceName";

生成出现问题的 JSON 对象的代码如下所示:

void Object::toJson(rapidjson::Document& json) const {
using namespace rapidjson;
json.SetObject();   // Reset and clear any existing
auto& allocator = json.GetAllocator();
json.AddMember(StringRef(kObjectKeyName), Value(name.c_str(), allocator), allocator);
json.AddMember(StringRef(kObjectKeyPrioritizeTable), Value(prioritizeTable), allocator);
json.AddMember(StringRef(kObjectKeyPrioritizeGreaterOn), Value(prioritizeGreaterOn), allocator);
}

请注意,kObjectKeyName定义为const char *kObjectKeyName = "name";

此类toJson的调用方如下所示:

using namespace rapidjson;
json.SetObject();   // Reset and clear any existing
auto& allocator = json.GetAllocator();
for (const auto& it : tables) {
Document iJson;
it.second->toJson(iJson);
json.AddMember(Value(it.first.c_str(), allocator), iJson, allocator);
}

部分问题可能源于我使用rapidjson::Document和分配器的方式。我相信一旦我拨打SetObject电话toJson调用就会以它自己的分配器结束。

我的计划是修改代码以使用Value而不是DocumenttoJson,然后将分配器作为参数传入。理想情况下,我不想这样做,主要是因为我很懒惰,并且希望签名相同,因此很容易在rapidjson或cppsrestsdk的儿子之间切换。

哦,是的,将文件输出为字符串的代码如下

std::ofstream out("output.json");
rapidjson::Document outDoc;
dataSet.toJson(outDoc);
rapidjson::StringBuffer buffer;
buffer.Clear();
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buffer);
outDoc.Accept(writer);
out << buffer.GetString();
out.close();

毫无疑问,我正在做一些奇怪/愚蠢的事情,因为最近才开始使用 rapidjson。我只是想缩小我的问题范围,更好地理解我的方式的错误。

如果修改要传入分配器的过程有效,则会出现。

我将toJson函数修改为

rapidjson::Value toJson(rapidjson::Document::AllocatorType& allocator);

在我的用法中,这意味着所有生成的Value,在需要时,都将使用基本Document的分配器。