Rapidjson:Doc.isObject()即使Doc.GetType()返回KobjectType,在解析后返回f

Rapidjson : doc.IsObject() returns false after parsing even though doc.GetType() returns kObjectType

本文关键字:返回 Doc GetType isObject 即使 Rapidjson KobjectType      更新时间:2023-10-16

我正在尝试使用RapidJson加载JSON文档。解析后,断言doc.isobject()失败了,我不明白为什么。我绝对确定文件名是正确的,我测试了JSONCONTENT:还可以。

这是加载代码:

std::ifstream file(filename);
std::string jsonContent( (std::istreambuf_iterator<char>(file)), (std::istreambuf_iterator<char>()));
rapidjson::Document doc;
doc.Parse < rapidjson::kParseStopWhenDoneFlag, rapidjson::UTF8<> >(jsonContent.c_str(), jsonContent.length());
assert(doc.IsObject());

这是加载的JSON:

{
"version": "170301",
"lang": "en"
}

这是输出:

 mytest:/home/dev/projects/myproject/src/loadjson.cpp:85:void loadfile(const std :: string&):断言`doc.isobject()'失败。未知位置(0):" mytest"中的致命错误:信号:sigabrt(申请流产请求)

我用GDB执行此操作,并获取以下信息(断言之前断点):

(gdb) p doc
$1 = {<rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >> = {static kDefaultArrayCapacity = 16, static kDefaultObjectCapacity = 16, data_ = {s = {
        length = 2, hashcode = 2, 
        str = 0x30000006a5b48 <error: Cannot access memory at address 0x30000006a5b48>}, ss = {
        str = "0200000002000000H[j0000"}, n = {i = {i = 2, 
          padding = "020000"}, u = {u = 2, padding2 = "020000"}, i64 = 8589934594, 
        u64 = 8589934594, d = 4.2439915829186759e-314}, o = {size = 2, capacity = 2, 
        members = 0x30000006a5b48}, a = {size = 2, capacity = 2, elements = 0x30000006a5b48}, f = {
        payload = "0200000002000000H[j0000", flags = 3}}}, 
  static kDefaultStackCapacity = 1024, allocator_ = 0x7fff00000000, ownAllocator_ = 0x691460, 
  stack_ = {allocator_ = 0x691460, ownAllocator_ = 0x0, stack_ = 0x0, stackTop_ = 0x0, 
    stackEnd_ = 0x0, initialCapacity_ = 0}, parseResult_ = {code_ = **rapidjson::kParseErrorNone,** 
    offset_ = 0}}
(gdb) p doc.GetType()
$2 = rapidjson::kObjectType
(gdb) p doc.IsObject()
$3 = false
(gdb) p jsonContent 
$4 = "{nt"version": "170301",nt"lang": "en"n}nn"

我尝试了此处列出的所有变体,并且我的所有变体都与所有变体失败了。

我无法通过以下代码重现问题:

#include <iostream>
#include "rapidjson/document.h"
int main() {
    rapidjson::Document doc;
    doc.Parse < rapidjson::kParseStopWhenDoneFlag, rapidjson::UTF8<> >("{"version": "170301","lang": "en"}");
    std::cout << doc.IsObject() << std::endl;
}

问题是您和米洛的代码在x86上工作。

实际上它可能在IBM服务器上的运行时失败(就我而言)。

最简单的猜测关键点是指针尺寸不匹配。Rapidjson假定指针大小不超过64位,而某些平台并非如此,因此RAPIDJSON_ALIGN以解析时似乎不是有效的对象来损坏数据。

特定的解决方案是通过编译标志(TERASPACELLP64)退回到64位大小的指针,并确保模块实际上进行Teraspace。

此外,预处理器命令#pragma datamodel (LLP64)可以与正确的设置验证一起使用。

也许这些技巧会有所帮助。

解决此问题的一种好方法是将std ::字符串复制到静态分配的char(byte)数组中。确保用静态分配的缓冲区来调用解析,而不是动态。如果您进行转换,请确保遵循JSON标准,Rapidjson将工作。

您基本上想将每个字符存储到一个字节插槽中:[0]:'{',[1]:'&quot;',[2]:; v&quot; v&quot; [3]:;...(希望您能明白这一点)。确保您不会存储类似的内容:[0]:'{',[1]:'',[2]:;&quot;&quot;&quot;&quot;...这将导致解析器的另一组问题。

基本上,这就是米洛在下面的回答中所要的。他使用了静态字符串,但是可以轻松地用静态分配的缓冲区替换,该缓冲区可以用STD :: String。

填充JSON字符