通过引用返回rapidjson::Document后写入文件为空问题求助
关于RapidJSON Document引用传递后写入空白文件的问题解答
首先可以明确说:通过引用方式返回rapidjson::Document是完全可行的,你的jsonTest方法本身逻辑没问题——毕竟它已经成功生成了完整的outputjsonTest.json文件,说明传入的Document在方法内部是被正确填充的。
那为什么调用完方法后自己写入outputruntest.json会是空白呢?我帮你分析几个可能的原因,以及对应的排查方案:
可能的问题点及排查步骤
1. Document的状态在方法返回后被意外修改
虽然你展示的代码里没有相关操作,但有没有可能在dMan.jsonTest(d);之后、写入文件之前,有其他代码修改了d的状态?比如不小心调用了d.SetNull()或者清空了成员?
可以在写入之前加几行调试代码,确认d的内容是否还在:
// 在写入outputruntest.json前添加 assert(d.IsObject()); // 确认Document是Object类型 assert(d.HasMember("Values")); // 确认"Values"成员存在 assert(d["Values"]["a"].GetInt() == 1); // 确认具体值正确
如果这些断言失败,说明d的内容确实被破坏了,需要排查中间的代码逻辑。
2. 写入文件的代码存在隐藏错误
虽然你的写入代码和jsonTest里的几乎一样,但还是有几个细节可以检查:
- 检查文件是否打开成功:避免因为权限、路径问题导致写入失败:
std::FILE* fp = fopen("outputruntest.json", "wb"); if (!fp) { printf("Failed to open file!\n"); return; } - 确认Accept方法执行成功:
Accept()会返回bool值表示是否成功遍历并写入文档,可以检查这个返回值:bool writeSuccess = d.Accept(writer); if (!writeSuccess) { printf("Failed to write Document!\n"); } - 手动刷新缓冲区:虽然
fclose会自动刷新缓冲区,但有时候手动调用os.Flush()可以避免奇怪的缓存问题:d.Accept(writer); os.Flush(); // 手动刷新 fclose(fp);
3. RapidJSON版本或环境相关的小问题
如果上述排查都没问题,可能是RapidJSON版本的bug(比如某些旧版本在多次调用Accept()后出现异常),或者编译器优化导致的意外问题。可以尝试:
- 更新到最新版本的RapidJSON
- 关闭编译器的过度优化选项(比如把
-O3改成-O2)
总结
你的引用传递思路是完全正确的,问题应该出在方法调用后的Document状态维护,或者写入代码的细节上。通过添加调试断言和错误检查,应该能很快定位到问题所在。
内容的提问来源于stack exchange,提问作者MSK
相关产品推荐
相关产品推荐

