cJSON 大概是用得最广的 C 语言 JSON 库之一,两个文件、无依赖、MIT 协议,嵌入式项目里到处能见到它。最近因为给项目加注释,顺便把它的数据结构和解析流程完整走了一遍,记在这里。
cJSON 结构体
所有 JSON 值——不管是对象、数组、字符串还是数字——都用同一个结构体表示,定义在 cJSON.h 里:
typedef struct cJSON {
struct cJSON* next; /* 同级下一个兄弟节点 */
struct cJSON* prev; /* 同级上一个兄弟节点 */
struct cJSON* child; /* 第一个子节点(仅 Array/Object 使用) */
int type; /* 节点类型(位掩码) */
char* valuestring; /* 字符串值(String/Raw 类型) */
int valueint; /* 整数值(已废弃,建议用 valuedouble) */
double valuedouble; /* 数字值(Number 类型) */
char* string; /* 键名(仅当节点是对象的子项时有效) */
} cJSON;
一个节点同时干两件事:表示一个值,也链接着同级的兄弟和下一级的子节点。next/prev 组成双向链表,child 指向第一个子节点。对象里的键名存在 string 字段里,字符串值存在 valuestring,数字用 valuedouble,valueint 已经标记为废弃了。
也就是说,整棵 JSON 树就是一棵用 next/prev 和 child 串起来的树状链表。
在 64 位系统上,一个节点大约占 64 字节(对齐后),具体布局如下:
[图示:64 位系统下 cJSON 结构体内存偏移]
| 偏移 (字节) | 大小 | 成员 |
|---|---|---|
| 0 | 8 字节 | next |
| 8 | 8 字节 | prev |
| 16 | 8 字节 | child |
| 24 | 4 字节 | type |


