# cJSON对象的构建
## 开始阅读源代码
**上面的文章中我们我们抓住了一条线,通过一个测试函数的实现来了解整个项目中的部分功能,当然,这不会覆盖所有的源代码,但我们会有一个清晰的思路来一步一步由点及面逐渐看清全局。这里有一个小小的经验,不要试图通篇浏览源代码以求了解所谓整体布局,相信我,大部分同学会从一头雾水到一头雾水,即便有毅力坚持到最后,也会是一个从入门到放弃的过程。**
### 1. 构建cJSON对象(结构)
+ cJSON结构:
```C
typedef struct cJSON
{
struct cJSON *next;
struct cJSON *prev;
struct cJSON *child;
int type;
char *valuestring;
int valueint;
double valuedouble;
char *string;
} cJSON;
```
+ 不难看出,这是构成链式结构的结点
+ 我们对这个结构体中的属性变量分成两部分
+ `struct cJSON *next`, `struct cJSON *prev`, `struct cJSON *child`, 三个cJSON类型指针分为一组,他们决定了数据结构的格式,其中next表示同级下一个节点,类似于json数据list类型的下一个元素,prev表示次节点的上一级节点,child代表这一节点的子节点
+ 此处注意理解next节点和child节点的区别
+ `int type`, `char *valuestring`, `int valueint`, `double valuedouble`, `char *string`这一组为数据成员,代表此节点的属性信息
+ 内存处理结构
另外一个很有趣的结构体叫做`internal_hooks` 定义代码如下:
```C
typedef struct internal_hooks
{
void *(*allocate)(size_t size);
void (*deallocate)(void *pointer);
void *(*reallocate)(void *pointer, size_t size);
} internal_hooks;
#if defined(_MSC_VER)
/* work around MSVC error C2322: '...' address of dillimport '...' is not static */
static void *internal_malloc(size_t size)
{
return malloc(size);
}
static void internal_free(void *pointer)
{
free(pointer);
}
static void *internal_realloc(void *pointer, size_t size)
{
return realloc(pointer, size);
}
#else
#define internal_malloc malloc
#define internal_free free
#define internal_realloc realloc
#endif
static internal_hooks global_hooks = {internal_malloc, internal_free, internal_realloc };
```
+ internal_hooks结构体包含三个函数指针,并且在上面的代码片段第28行处进行了实例化,定义了静态变量global_hooks
+ 可能会让很多刚刚接触C语言的同学困惑的地方是
```C
#if defined(_MSC_VER)
..........
#else
..........
#endif
```
首先声明,这并不是C语言,所有以‘#’为开头的代码都是`预编译指令`,此处不做过多解释,会在后面的博文中对预编译指令单独讲解
+ 言归正传,这28行代码的结果非常简单,我们得到了一个静态变量global_hooks,其中包含三个成员变量,均为函数指针,指向我们非常熟悉的`malloc`, `free`, `realloc`函数
+ 当然,这样做是有原因的,其中一点是为了跨平台,其他妙处在此处不做过多解释,在使用的过程中自然会发现。
+ 构建cJSON结构
+ 源码阅读到这里,针对构建cJSON结构这一需求
cJSON *root = (cJSON *)malloc(sizeof(cJSON));
memset(root, '\0', sizeof(cJSON));
这样我们便可以得到一个空的cJSON结构
+ 在源码中,同样是这样的逻辑
+ `cJSON_CreateObject`函数中通过调用`cJSON_New_Item`函数,得到`cJSON`类型指针`item`,将其`type`属性赋值为`cJSON_Object`
+ 在`cJSON_New_Item`函数中,传入`global_hooks`的地址,`(cJSON*)hooks->allocate(sizeof(cJSON));`这句代码调用了global_hooks的allocate,通过上面的定义我们发现,实际上调用的是malloc函数开辟了一段类型为cJSON的内存空间。
+ 将这段开辟的空间初始化为‘\0’后返回
**这里我们了解了cJSON基本数据结构以及其初始化方法, 后面的博文我们将继续了解插入数据的相关操作及实现细节**