学习使用cJSON过程的一些发现和总结,不涉及具体的函数
cJSON简介
cJSON是一个快速,高性能的json解析器,由C语言编写,仅包含cJSON.c和cJSON.h两个文件,不支持跨平台;跨平台推荐纯lua写的dkjson
cJSON结构体
cJSON结构体的组成:
1 | typedef struct cJSON { |
其中
next指向链表中下一个兄弟节点,prev指向本节点前一个节点child节点只有对象和数组有,并且child节点是双向链表的头节点,child的prev一般为NULL,不指向任何节点,双向链表的最后一个兄弟节点的next是无指向的type取值有Null/True/False/Number/String/Array/Object,这些值类型都在cJSON.h中通过宏定义了String类型节点有valuestring,Number类型节点有valueint和valuedoublestring表示节点的名称,所有的节点都是一个链表,都具有string值
cJSON默认所有值都为0,除非额外为其赋有意义的值
cJSON树结构
cJSON使用树结构存储JSON的各个节点,而这个树结构是使用双向链表实现的(实线表示节点间有真实的引用关系,而虚线表示逻辑上的引用关系):
- 树结构的每一层都是一个双向链表,表示一堆兄弟节点
- 当前层的所有节点都是当前链表头节点的父节点的子节点
下面举例说明:
1 | { |
name和format节点组成一个链表,type、width、height、interlace和frame rate节点组成一个链表- 根节点包含节点类型
Object和子节点name - 子节点包含节点名称
name、节点值Jack ("Bee") Nimble和兄弟节点format format节点包含节点类型Object、节点名称format和子节点typetype节点包含节点类型String、节点名称type、节点值rect和兄弟节点widthwidth节点包含节点类型Number、节点名称width、节点值1920和兄弟节点heightheight节点包含节点类型Number、节点名称height、节点值1080和兄弟节点interlaceinterlace节点包含节点类型False、节点名称interlace和兄弟节点frame rateframe rate节点包含节点类型Number、节点名称frame tate和节点值25
cJSON内存管理
cJson分为自动和手动两种使用方式:
- 在自动模式下,
cJSON使用默认的malloc和free函数管理内存,在cJSON中,每个节点都是malloc而来,每个节点的string和valuestring也是malloc而来,使用cJSON_Delete函数可以递归释放JSON树中malloc的节点内存和字符内存,使用cJSON_Print函数后,则需要手动释放cJSON_Print函数分配的内存,避免内存泄露 - 在手动模式下,
cJSON提供了钩子函数来帮助用户自定义内存管理函数,如果不设置,这默认为malloc和free
1 | struct cJSON_Hooks js_hook = {xxx_malloc, xxx_free}; |
cJSON序列化
cJSON序列化就是把cJSON输出,有两种形式:
- 格式化输出
char *cJSON_Print(cJSON *item); - 压缩输出
char *cJSON_PrintUnformatted(cJSON *item);
需要注意的是cJSON采用了预先将要输的内容全部以字符串形式存储在内存中,最后输出整个字符串的方法,而不是边分析json数据边输出,所以对于比较大的json数据来说,内存就是个问题了
