2017-03-17 130 views
1

我使用cJson为C,到嵌入​​式平台,打造这样一个JSON的长度:cJson如何计算打印缓冲区

{"ProtocolVersion":1,"ID":"123","Zone":"xyz","MessageType":42,"Message":"Json payload MSG #6"} 

要做到这一点我用cJson提供了这个功能:

jsonObject = cJSON_CreateObject(); 

    /* Add Protocol Version */ 
    cJSON_AddNumberToObject(jsonObject, "ProtocolVersion", 1); 
    /* Add Machine Id */ 
    cJSON_AddStringToObject(jsonObject, "ID", idStr); 
    /* Add Market */ 
    cJSON_AddStringToObject(jsonObject, "Zone", xyzStr); 
    /* Add Message Type */ 
    cJSON_AddNumberToObject(jsonObject, "MessageType", typeNum); 
    /* Add Message */ 
    cJSON_AddStringToObject(jsonObject, "Message", msgStr); 

要创建我利用的功能的JSON:

cJSON_PrintPreallocated(jsonObject, *jsonMessage, *jsonMessageLen, 0); 

我宁愿传给cJson我的应用A预分配的缓冲区n和我基本上通过总和每个Key和Object的长度来计算缓冲区长度。

例如:strlen的( “区”)+的strlen(xyzStr)+ ... +的 “” +数量的{}数+数量,+的数量:

这样我获得我的JSON的确切长度。

不幸的是,函数“cJSON_PrintPreallocated”由于不正确的缓冲区长度(它似乎很短)而失败。

如果我添加一个额外的30字节到我的“jsonMessage”一切正常。

我在哪里错了?

哪个是计算cJson所需缓冲区长度的最佳方法?

谢谢!

+0

仔细思考如何构建JSON。它不是_just_键和值,以及各种分隔符。打开示例JSON文档,查看除键和值以外的其他字符可以在哪里。 –

+0

另外,为什么'jsonMessageLen'是一个指针?如果不是,则需要打开警告,因为您试图将该值作为非指针。 –

+0

使用使用指向jsonMessageLen的指针,因为我动态分配jsonMessage。 – Federico

回答

1

打印数字时,cJSON保守地在输出缓冲区中保留64个字节,因为它无法确定sprintf打印数字的时间。如果数字为1,这可能意味着cJSON请求的字节数比实际需要的多63字节。

这可能会在cJSON的未来版本中发生变化,但现在有了解决方法。

为了安全起见,您应该始终使您的缓冲区比您期望的要长63个字节。

UPDATE:

这已被更新。由于版本1.4.6只需要5个额外的字节。

+0

感谢您的回复。我将这个字节数加在安全的一边。 – Federico

+0

我还将该信息添加到未来的cJSON.h头文件中。 – FSMaxB