如何修复 RapidJSON Assertion `!hasRoot_' failed.

问题:

你的程序正在使用 RapidJSON,但运行时你看到类似这样的错误消息

rapidjson_assertion.txt
rapidjson-example: /usr/include/rapidjson/writer.h:452: void rapidjson::Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags>::Prefix(rapidjson::Type) [with OutputStream = rapidjson::BasicOStreamWrapper<std::basic_ostream<char> >; SourceEncoding = rapidjson::UTF8<>; TargetEncoding = rapidjson::UTF8<>; StackAllocator = rapidjson::CrtAllocator; unsigned int writeFlags = 0]: Assertion `!hasRoot_' failed.

解决方案

你正在为多个 Document 使用一个 Writer。虽然你可以为任意数量的文档使用支持 WriterStream,但每个 Writer 只能使用一次!

要修复此问题,为你打算写入的每个文档创建一个 Writer 实例(在相同的输出 Stream 上)。

复现问题的最小代码:

rapidjson_hasroot_repro.cpp
#include <iostream>
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/ostreamwrapper.h>
using namespace rapidjson;
using namespace std;

Document generateDoc() {
    // 生成文档:{"text": "Hello JSON!"}
    Document doc;
    doc.SetObject(); // 使 doc 成为对象!
    doc.AddMember("text", "Hello JSON!", doc.GetAllocator());
    return doc;
}

int main() {
    // 写入 stdout
    OStreamWrapper out(cout);
    Writer<OStreamWrapper> writer(out);
    // 写入第一个文档...
    generateDoc().Accept(writer);
    cout << "\nFirst document written!" << endl;
    // 写入第二个文档...
    generateDoc().Accept(writer);
    cout << "\nSecond document written!" << endl;
}

该代码将以上面列出的错误消息崩溃:

rapidjson_hasroot_crash_output.txt
{"text":"Hello JSON!"}
First document written!
rapidjson-example: /usr/include/rapidjson/writer.h:452: void rapidjson::Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags>::Prefix(rapidjson::Type) [with OutputStream = rapidjson::BasicOStreamWrapper<std::basic_ostream<char> >; SourceEncoding = rapidjson::UTF8<>; TargetEncoding = rapidjson::UTF8<>; StackAllocator = rapidjson::CrtAllocator; unsigned int writeFlags = 0]: Assertion `!hasRoot_' failed.
zsh: abort (core dumped)  ./rapidjson-example

这是修复后的代码,将按预期工作:

rapidjson_hasroot_fixed.cpp
#include <iostream>
#include <rapidjson/document.h>
#include <rapidjson/writer.h>
#include <rapidjson/ostreamwrapper.h>
using namespace rapidjson;
using namespace std;

Document generateDoc() {
    // 生成文档:{"text": "Hello JSON!"}
    Document doc;
    doc.SetObject(); // 使 doc 成为对象!
    doc.AddMember("text", "Hello JSON!", doc.GetAllocator());
    return doc;
}

int main() {
    // 写入 stdout
    OStreamWrapper out(cout);
    // 写入第一个文档...
    Writer<OStreamWrapper> writer1(out);
    generateDoc().Accept(writer1);
    cout << "\nFirst document written!" << endl;
    // 写入第二个文档...
    Writer<OStreamWrapper> writer2(out); // 与 writer1 相同的输出流!
    generateDoc().Accept(writer2);
    cout << "\nSecond document written!" << endl;
}

输出:

rapidjson_hasroot_fixed_output.txt
{"text":"Hello JSON!"}
First document written!
{"text":"Hello JSON!"}
Second document written!

Check out similar posts by category: C/C++