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

时间:2017-03-17 18:28:33

标签: c++ rapidjson

我目前有一个我正在使用的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": {
        "name\u0000refere": "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和分配器的方式。我相信toJson电话会在我拨打SetObject电话后以自己的分配器结束。

我的计划是修改代码以在Value中使用Document而不是toJson,然后将分配器作为参数传递。理想情况下,我不想这么做,主要是因为我很懒,想要签名,所以很容易在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时,我正在做奇怪/愚蠢的事情。我只是想缩小我的问题范围,更好地理解我的方式错误。

1 个答案:

答案 0 :(得分:0)

如果修改传入分配器的进程,则会出现。

我将toJson功能修改为

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

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