cJSON源码分析1-基础

宏定义

调用方式

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);
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值