目录
在使用MQTT传输数据的时候,经常使用到JSON包,来进行数据的交互,这篇文章讲一下该如何使用。
cJSON的源码文件只有两个:
cJSON.c
cJSON.h
下载地址可以在github下载,地址如下:
GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C
将这两个文件下载之后,添加到项目中,其它.C文件调用的时候,需要包含头文件cJSON.h即可,文件在MDK中的位置如下:
cJSON是用一个结构体来表示一个JSON数据,定义在cJSON.h中,查看如下源码:
- /* The cJSON structure: */
- typedef struct cJSON
- {
- /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
- struct cJSON *next;
- struct cJSON *prev;
- /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
- struct cJSON *child;
-
- /* The type of the item, as above. */
- int type;
-
- /* The item's string, if type==cJSON_String and type == cJSON_Raw */
- char *valuestring;
- /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
- int valueint;
- /* The item's number, if type==cJSON_Number */
- double valuedouble;
-
- /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
- char *string;
- } cJSON;
不是存贮整片的JSON数据,而是按照每条数据进行存储的。使用next指针和prev指针进行链表,存储整片的JSON数据。
说了这么多,我们实际操作一下,找一块STM32F开发板,测试一下。
-
- uart_init(115200);
-
- #include "cJSON.h"
- {
- "我的名字": "老刘",
- "公众号": "数独机",
- "年龄": 11,
- "性别": "男",
- "电话": 186,
- "地址": "一般人不告诉",
- "我是嵌套的cJSON": {
- "号码": 9527,
- "传真": 5510,
- "淘宝店": "This熏"
- },
- "我是嵌套的数组": [{
- "我是奇数循环": 0
- }, {
- "我是偶数循环": "12365"
- }, {
- "我是奇数循环": 2
- }, {
- "我是偶数循环": "12365"
- }, {
- "我是奇数循环": 4
- }]
- }
- cJSON* main_root = NULL;
- cJSON* main_m_root = NULL;
- cJSON* main_l_root = NULL;
- cJSON* obj=NULL;
- char* response_str = NULL;
main_root = cJSON_CreateObject();
豪横的在链表中添加节点
- cJSON_AddStringToObject(main_root, "我的名字", "老刘");
- cJSON_AddStringToObject(main_root, "公众号", "数独机");
- cJSON_AddNumberToObject(main_root, "年龄", 11);
- cJSON_AddStringToObject(main_root, "性别", "男");
- cJSON_AddNumberToObject(main_root, "电话", 186);
- cJSON_AddStringToObject(main_root, "地址", "一般人不告诉");
-
- main_m_root = cJSON_CreateObject();
- cJSON_AddNumberToObject(main_m_root, "号码", 9527);
- cJSON_AddNumberToObject(main_m_root, "传真", 5510);
- cJSON_AddStringToObject(main_m_root, "淘宝店", "This熏");
- cJSON_AddItemToObject(main_root, "我是嵌套的cJSON", main_m_root);
-
- main_l_root=cJSON_CreateArray();
- cJSON_AddItemToObject(main_root,"我是嵌套的数组",main_l_root);
- for(i=0;i<5;i++)
- {
- obj=cJSON_CreateObject();
- cJSON_AddItemToArray(main_l_root,obj);
- if(i%2 == 0) cJSON_AddNumberToObject(obj, "我是奇数循环", i);
- else cJSON_AddStringToObject(obj, "我是偶数循环", "12365");
- }
- response_str = cJSON_Print(main_root);
- printf("%s\n",response_str);
解包的函数只有一个:
-
- CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
还是用例子进行讲解:
将串口的数据完全接收到一个大的缓冲区里面,当然这个数据也可以来自wifi或者网络。
-
- if(GET_STOP_flag)
- {
- for(i=0;i<(cJSON_pack_StopP-cJSON_pack_FistP)+1;i++)
- {
- MessageTmp[i] =WIFI_RC_buf[cJSON_pack_FistP-1+i];
- }
- }
- GET_STOP_flag //为停止接收标志;
- cJSON_pack_StopP //停止指针位置
- cJSON_pack_FistP //开始指针位置
- MessageTmp //临时的数组
只需要对临时的数组进行操作即可。开辟内存空间,将数组转换为字符串。
- MessageStrTmp = (char *)cJSON_malloc(sizeof(char) * (sizeof(MessageTmp) + 1));
- strncpy(MessageStrTmp, MessageTmp, sizeof(MessageTmp));
使用解包函数
-
- //接收解包过程
- Thisxun_root = cJSON_Parse(MessageStrTmp);
- Thisxun_root_type = cJSON_GetObjectItem(hiss_root,"type")->valuestring;
- if(strcmp(Thisxun_root_type,TYPE_USER_INFO_SYNC)==0)
- {
- Thisxun_insDetail = cJSON_GetObjectItem(Thisxun_root,"insDetail");
- userID = cJSON_GetObjectItem(Thisxun_insDetail,"userId")->valuestring;
- password = cJSON_GetObjectItem(Thisxun_insDetail,"password")->valuestring;
- }
每次封包和解包结束之后,都要及时释放内存:
-
- cJSON_Delete(Thisxun_root);
- cJSON_free(MessageStrTmp);
对于单片机而言,需要修改Heap_Size
本文来源网络,免费分享知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除!