首页 > 代码库 > cJSON 使用笔记

cJSON 使用笔记

                                                                                                        缘      起                                                                                                     

      最近在stm32f103上做一个智能家居的项目,其中选择的实时操作系统是 rt_thread OS v1.2.2稳定版本,其中涉及到C和java(android)端数据的交换问题,经过讨论和研究,选择了json格式的数据进行交互。当然,如果自己去写一个json解析器,有点重造轮子的嫌疑。于是使用了开源的json解析器。考虑到是嵌入式平台,在一位朋友的推荐下,选择了轻量级别的cJSON。

                                                                                                        使      用                                                                                                     

       cJSON 开源项目位置:  http://sourceforge.net/projects/cjson/

       cJSON,目前来说,就只有两个文件,一个cJSON.c 一个cJSON.h文件。使用的时候,自己创建好一个main.c文件后,如果是在linux pc上,请使用以下命令进行编译:

 

1 gcc -g -Wall *.c -l m

就会默认生成一个 a.out文件,执行即可。在linux下编译的时候,注意链接 libm 库。

       整个项目都是以极标准的C来写的,意思说,可以跨各种平台使用了。不过,还是有两三处需要微调一下<针对stm32f103  + rt_thread >。其中修改一下malloc & free & size_t 这三个东西:

 46 static void *(*cJSON_malloc)(size_t sz) = malloc; 47 static void (*cJSON_free)(void *ptr) = free;---------------------------------------- 46 static void *(*cJSON_malloc)(size_t sz) = rt_malloc; 47 static void (*cJSON_free)(void *ptr) = rt_free;
 60 void cJSON_InitHooks(cJSON_Hooks* hooks) 61 { 62     if (!hooks) { /* Reset hooks */ 63         cJSON_malloc = malloc; 64         cJSON_free = free; 65         return; 66     } 67  68     cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; 69     cJSON_free   = (hooks->free_fn)?hooks->free_fn:free; 70 }---------------------------------------------------- 60 void cJSON_InitHooks(cJSON_Hooks* hooks) 61 { 62     if (!hooks) { /* Reset hooks */ 63         cJSON_malloc = rt_malloc; 64         cJSON_free = rt_free; 65         return; 66     } 67  68     cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:rt_malloc; 69     cJSON_free   = (hooks->free_fn)?hooks->free_fn:rt_free; 70 }

free & malloc就这么两个地方要修改一下吧,其中size_t 这个应该是在 .h 文件修改,主要是rtt的 rt_malloc 和这里的malloc使用的不同,所以修改了下---不一定非要修改。

所以,这东西说实话,也不存在什么移植不移植的问题了。很轻松的就可以在各个平台使用了。

                                                                                                   例       程                                                                                                          

      不对json的格式进行说明了,下面直接记下使用方法了。

      第一,创建json数据串。这数据串,可能是对象,也可能是数组,也可能是它们的各种组合,其中再加上一些键值对。有一点要先说明:它们的组合,符合父子继承格式--这也是json数据串的特点。

     <1>  创建一个对象,并在这个对象里面添加一个字符串键值和一个数字键值:

 1 int create_js(void) 2 { 3     cJSON *root; 4     /*create json string root*/ 5     root = cJSON_CreateObject(); 6     if(!root) { 7         DEBUG("get root faild !\n"); 8         goto EXIT; 9     }else DEBUG("get root success!\n");10 11     {12         cJSON * js_body ;13 14         const char *const body = "body";15         cJSON_AddItemToObject(root, body, js_body=cJSON_CreateObject());16         cJSON_AddStringToObject(js_body,"name","xiaohui");17         cJSON_AddNumberToObject(js_body,"value",600);18         {19         char *s = cJSON_PrintUnformatted(root);20         if(s){21             DEBUG("create js string is %s\n",s);22             free(s);23         }24         }25         cJSON_Delete(root);26     }27 28     return 0;29 EXIT:30     return -1;31 }32 33 int main(int argc, char **argv)34 {35     create_js();36     return 0;37 }

运行结果:

1 create js string is  {"body":{"name":"xiaohui","value":600}}

说明: 创建根对象,使用  cJSON_CreateObject(); 这个API,返回的是一个 cJSON的指针,注意,在这个指针用完了以后,需要手工调用 cJSON_Delete(root); 进行内存回收。

创建body对象的时候,是在根对象的基础上进行创建,而插入name 和value的时候,是以body为父节点。需要注意的是  json 格式的数据,虽然也是一个字符串的样子,但这个时候还是无法当成普通的字符串进行使用,需要调用 cJSON_PrintUnformatted(root) 或者 cJSON_Print(root);来将json对象转换成普通的字符串,并且都是以该json对象的根为基点。两个API的区别即是:一个是没有格式的:也就是转换出的字符串中间不会有"\n" "\t"之类的东西存在,而cJSON_Print(root);打印出来是人看起来很舒服的格式。仅此而已。

<2> 创建一个数组,并向数组添加一个字符串和一个数字:

 1 int create_js(void) 2 { 3     cJSON *root, *js_body; 4     root = cJSON_CreateArray(); 5     cJSON_AddItemToArray(root, cJSON_CreateString("Hello world")); 6     cJSON_AddItemToArray(root, cJSON_CreateNumber(10));  7     { 8 //        char *s = cJSON_Print(root); 9         char *s = cJSON_PrintUnformatted(root);10         if(s){11             DEBUG(" %s \n",s);12             free(s);13         }14     }15     if(root)16     cJSON_Delete(root);17 18     return 0;19 EXIT:20     return -1;21 }22 23 int main(int argc, char **argv)24 {25     create_js();26     return 0;27 }

运行结果:

1 ["Hello world",10]

<3> 对象里面包括一个数组,数组里面包括对象,对象里面再添加一个字符串和一个数字:

 1 int create_js(void) 2 { 3     cJSON *root, *js_body, *js_list; 4     root = cJSON_CreateObject(); 5     cJSON_AddItemToObject(root,"body", js_body = cJSON_CreateArray()); 6     cJSON_AddItemToArray(js_body, js_list = cJSON_CreateObject()); 7     cJSON_AddStringToObject(js_list,"name","xiaohui"); 8     cJSON_AddNumberToObject(js_list,"status",100); 9 10     {11         //        char *s = cJSON_Print(root);12         char *s = cJSON_PrintUnformatted(root);13         if(s){14             DEBUG(" %s \n",s);15             free(s);16         }17     }18     if(root)19         cJSON_Delete(root);20 21     return 0;22 EXIT:23     return -1;24 }25 26 int main(int argc, char **argv)27 {28     create_js();29     return 0;30 }

运行结果:

1 {"body":[{"name":"xiaohui","status":100}]}

<4>其他组合就依次类推,只要搞清楚父子关系即可。随便嵌套随便玩。不再贴了。

   <第二, 解析json数据串>

   步骤: 1  先将普通的json 字符串 处理成 json对象格式。 2  根据关键字进行解析,解析的时候,需要根据关键字值的类型进行判断,而这些类型,已经在cJSON.h里面写明白了,包括:对象、数组、普通字符串、普通变量等等。

   <偷个懒吧,将自己学习的时候用的资料现贴过来,后面休息一下再详细补充自己在工程中的解析方法>

http://blog.csdn.net/xukai871105/article/details/17094113

http://blog.sina.com.cn/s/blog_a6fb6cc90101ffme.html

 

<当然,他写的比较简洁,还有些可以补充的---其实我已经在上面使用文字进行补充过了。当然,不同的工程,可能解析的方法和侧重点并不相同>

 

cJSON 使用笔记