宏定义
调用方式
stdcall: C++标准调用方式。
- 参数从右向左依次压入堆栈.
- 由被调用函数自己来恢复堆栈,称为自动清栈。
- 函数名自动加前导下划线,后面紧跟着一个@,其后紧跟着参数的大小。
cdecl调用方式又称为C调用方式,是C语言缺省的调用方式。
- 参数从右向左依次压入堆栈.
- 由调用者恢复堆栈,称为手动清栈。
- 函数名自动加前导下划线。
#define CJSON_CDECL __cdecl
#define CJSON_STDCALL __stdcall
版本
//cJSON的版本号 1.7.12
#define CJSON_VERSION_MAJOR 1
#define CJSON_VERSION_MINOR 7
#define CJSON_VERSION_PATCH 12
//获取版本号
CJSON_PUBLIC(const char*) cJSON_Version(void)
{
static char version[15];
sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH);
return version;
}
类型定义
//cJSON的类型,定义为整数
#define cJSON_Invalid (0) //无效
#define cJSON_False (1 << 0) //false
#define cJSON_True (1 << 1) //true
#define cJSON_NULL (1 << 2) //null
#define cJSON_Number (1 << 3) //number,数字
#define cJSON_String (1 << 4) //string, 字符串
#define cJSON_Array (1 << 5) //Array, 数组
#define cJSON_Object (1 << 6) //Object, 对象
#define cJSON_Raw (1 << 7) //Raw, 原生JSON
cJSON结构
cJSON把JSON对象抽象成树结构
/* cJSON的结构 */
typedef struct cJSON
{
struct cJSON *next; //同一级元素使用双向链表存储,用于访问同一级的数组/对象
struct cJSON *prev;
struct cJSON *child;//如果是object/array,child为指向第一个子节点的指针
int type; //cJSON的类型
char *valuestring; //字符串的值(cJSON_String/cJSON_Raw)
int valueint; //int值
double valuedouble;//数字的值(cJSON_Number才有)
char *string; //节点的名字
} cJSON;
bool值定义
cJSON_bool类型实际为int类型
//cJSON_bool定义为int
typedef int cJSON_bool;
内存管理
最大深度
//cJSON最大的深度,防止栈溢出
#ifndef CJSON_NESTING_LIMIT
#define CJSON_NESTING_LIMIT 1000
#endif
HOOK
cJSON内存管理使用HOOK技术,方便用户自定义自己的内存管理函数。
typedef struct cJSON_Hooks
{
void *(CJSON_CDECL *malloc_fn)(size_t sz);
void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
cJSON_InitHooks中,传入cJSON_Hooks,会修改默认的malloc/free。具体函数如下:
//初始化malloc, realloc, free的HOOK。使用时需要传入cJSON_Hooks指向,
//定义用户自己的内存管理函数
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks)
{
//设置为默认的内存管理
if (hooks == NULL)
{
global_hooks.allocate = malloc;
global_hooks.deallocate = free;
global_hooks.reallocate = realloc;
return;
}
global_hooks.allocate = malloc;
if (hooks->malloc_fn != NULL)
{
//使用用户自定义的allocate
global_hooks.allocate = hooks->malloc_fn;
}
global_hooks.deallocate = free;
if (hooks->free_fn != NULL)
{
global_hooks.deallocate = hooks->free_fn;
}
global_hooks.reallocate = NULL;
if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free))
{
global_hooks.reallocate = realloc;
}
}
使用自定义内存管理的方法:
cJSON_InitHooks *hooks = NULL;
hooks = (cJSON_InitHooks *)calloc(1, sizeof(cJSON_InitHooks));
hooks->malloc_fn = my_malloc;
hooks->free_fn = my_free;
cJSON_InitHooks(hooks);