Toggle navigation
首页
(current)
问答
文章
话题
商城
登录
注册
12、RDA8910CSDK二次开发:c语言中最好用的JSON解析库---cJSON
air724UG
csdk
RDA8910
cjson
# 目录 [点击这里查看所有博文](https://blog.csdn.net/weixin_44570083/article/details/104285283) 本系列博客所述资料`均来自合宙官方`,并不是本人原创(只有博客是...
# 目录 [点击这里查看所有博文](https://blog.csdn.net/weixin_44570083/article/details/104285283) 本系列博客所述资料`均来自合宙官方`,并不是本人原创(只有博客是自己写的),csdk只是得到了`口头的允许公开授权`。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,`没有为自己谋取私利的想法`。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。 本系列博客基于紫光展锐的`RDA8910 LTE Cat 1` bis芯片平台开发。理论上适用于合宙的Air720U、Air724U、广和通L610以及安信可的cat-01模块。 各个厂家的部分配置文件可能不一样,也许会导致设备出现奇怪的问题,其他的模块我也不确定能不能用,自行测试。但是有一点`编译下载和监视流程基本一样`,可供参考。 先不管支不支持,如果你用的模块是是紫光展锐的RDA8910,那都不妨一试,也许会有意外收获(`也有可能变砖,慎重!!!`)。 我使用的是`Air724UG`开发板,如果在其他模块上不能用,那也不要强怼,也许是开发包不兼容吧。这里的代码是没有问题的。例程仅供参考! # 一、前言 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种由道格拉斯·克罗克福特构想和设计、轻量级的数据交换语言,该语言以易于让人阅读的文字为基础,用来传输由属性值或者序列性的值组成的数据对象。尽管JSON是JavaScript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。 JSON 数据格式与语言无关,脱胎自JavaScript,但当前很多编程语言都支持 JSON 格式数据的生成和解析。JSON 的官方 MIME 类型是 application/json,文件扩展名是 .json。 JSON 解析器和 JSON 库支持许多不同的编程语言。 JSON 文本格式在语法上与创建 JavaScript 对象的代码相同。 由于这种相似性, 无需解析器, JavaScript 程序能够使用内建的 eval() 函数, 用 JSON 数据来生成原生的 JavaScript 对象。 JSON 是存储和交换文本信息的语法。 类似 XML。 JSON 比 XML 更小、 更快, 更易解析。 JSON 具有自我描述性, 语法简洁, 易于理解。 关于JSON的介绍,需要了解的兄弟们请参考我的`合宙Air模块Luat开发`专题,`第10篇`文章[JSON字符串的生成与解析](https://blog.csdn.net/weixin_44570083/article/details/105285966)。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200615004541627.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDU3MDA4Mw==,size_16,color_FFFFFF,t_70) 总之就是一句话。JSON很常见,虽然与 JavaScript 紧密相连,但 JSON 与语言无关,JSON 使用与其他语言类似的约定(例如,C,C ++,Java,Perl ,Lua和 Python),使 JSON 成为理想的数据交换语言。 在c语言中同样有很多用于JSON生成和解析的库,其中免费开源好用的当属cJSON。那么今天我们就来耍一下。 cJSON库文件在demo里面的`cJSON`例程有提供,直接拷贝一份出来即可使用。不需要做其他的改动。 # 二、编写测试程序 ## 2.1、了解本例程所用到的函数 使用cJSON服务需要包含`#include "cJSON.h""`头文件,我们这里只用到了13个函数,分别是: >/**JSON解析 >提供一个JSON块,这将返回一个您可以查询的cJSON对象。 > *@param `value`:JSON字符串 *@return cJSON对象指针 **/ * CJSON_PUBLIC(cJSON *) `cJSON_Parse`(const char *value) > /***从JSON对象中获取键值对。不区分大小写。 *@param `object`:要查询的cJSON对象 `string`:要查询的键值对 *@return cJSON对象指针 **/ * CJSON_PUBLIC(cJSON *) `cJSON_GetObjectItem`(const cJSON * const object, const char * const string) > /*判断该对象是不是字符串类型 *@param `object`:要查询的cJSON对象 *@return 真值,是字符串类型 **/ * CJSON_PUBLIC(cJSON_bool) `cJSON_IsString`(const cJSON * const item); > /*判断该对象是不是数字类型 *@param `object`:要查询的cJSON对象 *@return 真值,是字数字类型 **/ * CJSON_PUBLIC(cJSON_bool) `cJSON_IsNumber`(const cJSON * const item) > /*获取数组(或对象)中的项目数。 *@param `object`:要查询的cJSON对象 *@return 项目数 **/ * CJSON_PUBLIC(int) `cJSON_GetArraySize`(const cJSON *array) > /*删除cJSON结构。 *@param `object`:要删除的cJSON对象 **/ * CJSON_PUBLIC(void) `cJSON_Delete`(cJSON *item) > /*创建一个cJSON对象 *@return 创建的对象 **/ * CJSON_PUBLIC(cJSON *) `cJSON_CreateObject`(void) > /*添加一个字符串到cJSON对象中 > *@param `object`:要添加的cJSON对象 > *@param `name`:要添加的键 > *@param `string`:要添加的值 *@return cJSON对象指针 **/ * CJSON_PUBLIC(cJSON*) `cJSON_AddStringToObject`(cJSON * const object, const char * const name, const char * const string); > /*添加一个数字到cJSON对象中 > *@param `object`:要添加的cJSON对象 > *@param `name`:要添加的键 > *@param `number`:要添加的值 *@return cJSON对象指针 **/ * CJSON_PUBLIC(cJSON*) `cJSON_AddNumberToObject`(cJSON * const object, const char * const name, const double number) > /*添加一个cJSON对象到cJSON对象中 > *@param `object`:要添加的cJSON对象 > *@param `name`:要添加的键 > *@param `item`:要添加的值 *@return cJSON对象指针 **/ * CJSON_PUBLIC(cJSON_bool) `cJSON_AddItemToObject`(cJSON *object, const char *string, cJSON *item); > /*创建一个数组对象 > *@param `numbers`:要创建的数组 > *@param `count`:数组的长度 *@return 创建的对象 **/ * CJSON_PUBLIC(cJSON *) `cJSON_CreateIntArray`(const int *numbers, int count) > /*将cJSON项目/实体/结构呈现为文本。 > *@param `item`:cJSON对象 *@return 字符串 **/ * CJSON_PUBLIC(char *) `cJSON_Print`(const cJSON *item) > /*释放内存 > *@param `object`:要释放的内存块 **/ * CJSON_PUBLIC(void) `cJSON_free`(void *object); ## 2.2、编写cJSON解析程序 解析程序负责将一个json格式的字符串转换成cJSON对象,并在其中查找需要的键值对。要注意的是,查找完毕后需要删除`cJSON_Parse`函数创建的父节点。 ```c // jsonRoot 是您要剖析的数据 //首先整体判断是否为一个json格式的数据 iot_debug_print("[cJSON_Test] cJSON_Parsing Start"); cJSON *pJsonRoot = cJSON_Parse(jsonRoot); //如果是否json格式数据 if (pJsonRoot != NULL) { iot_debug_print("[cJSON_Test] cJSON TRUE"); iot_debug_print("[cJSON_Test] cJSON:%s", jsonRoot); } else { iot_debug_print("[cJSON_Test] cJSON ERROR"); } //解析imei字段字符串内容 cJSON *pimeiAdress = cJSON_GetObjectItem(pJsonRoot, "imei"); //判断imei字段是否json格式 if (pimeiAdress) { //判断mac字段是否string类型 if (cJSON_IsString(pimeiAdress)) iot_debug_print("[cJSON_Test] get imeiAdress:%s", pimeiAdress->valuestring); } else iot_debug_print("[cJSON_Test] get imeiAdress failed"); //解析Num字段int内容 cJSON *pNumber = cJSON_GetObjectItem(pJsonRoot, "Num"); //判断Num字段是否存在 if (pNumber) { //判断mac字段是否数字整型类型 if (cJSON_IsNumber(pNumber)) iot_debug_print("[cJSON_Test] get Num:%d", pNumber->valueint); } else iot_debug_print("[cJSON_Test] get Num failed"); //解析value字段内容,判断是否为json cJSON *pValue = cJSON_GetObjectItem(pJsonRoot, "Value"); if (pValue) { //进一步剖析里面的name字段:注意这个根节点是 pValue cJSON *pName = cJSON_GetObjectItem(pValue, "name"); if (pName) { if (cJSON_IsString(pName)) iot_debug_print("[cJSON_Test] get value->Name:%s", pName->valuestring); } else iot_debug_print("[cJSON_Test] get pValue->pName failed"); //进一步剖析里面的age字段:注意这个根节点是 pValue cJSON *pAge = cJSON_GetObjectItem(pValue, "age"); if (pAge) { if (cJSON_IsNumber(pAge)) iot_debug_print("[cJSON_Test] get value->Age:%d", pAge->valueint); } else iot_debug_print("[cJSON_Test] get pValue->pAge failed"); //进一步剖析里面的blog字段:注意这个根节点是 pValue cJSON *pBlog = cJSON_GetObjectItem(pValue, "blog"); if (pBlog) { if (cJSON_IsString(pBlog)) iot_debug_print("[cJSON_Test] get value->pBlog:%s", pBlog->valuestring); } else iot_debug_print("[cJSON_Test] get pValue->pBlog failed"); } else iot_debug_print("[cJSON_Test] get pValue failed"); //剖析数组 cJSON *pArry = cJSON_GetObjectItem(pJsonRoot, "hexArry"); if (pArry) { //获取数组长度 int arryLength = cJSON_GetArraySize(pArry); iot_debug_print("[cJSON_Test] get arryLength:%d", arryLength); //逐个打印 int i; for (i = 0; i < arryLength; i++) iot_debug_print("[cJSON_Test] get cJSON_GetArrayItem(pArry, %d)= %d", i, cJSON_GetArrayItem(pArry, i)->valueint); } else iot_debug_print("[cJSON_Test] get pArry failed"); //释放内存 cJSON_Delete(pJsonRoot); iot_debug_print("[cJSON_Test] cJSON_Parsing Stop"); ``` 相比Luat中的json解析,cJSON用起来真的是太复杂了。 ## 2.3、编写cJSON生成程序 生成程序,首先创建一个空的对象(实际是一个链表),然后将不同的键值对依次插入。全部插入完成后,打印查看,最后删除`cJSON_CreateObject`函数创建的父对象`pRoot` 。 ```c //取一下本地的station的mac地址,保存在全局变量tempMessage iot_debug_print("[cJSON_Test] cJSON_Generate Start"); cJSON *pRoot = cJSON_CreateObject(); //新增一个字段imei到根点,数值是tempMessage char tempMessage[] = "8661111111111111"; cJSON_AddStringToObject(pRoot, "imei", tempMessage); //新增一个字段number到根点,数值是2 cJSON_AddNumberToObject(pRoot, "number", 2020); cJSON *pValue = cJSON_CreateObject(); cJSON_AddStringToObject(pValue, "name", "cx"); cJSON_AddNumberToObject(pValue, "age", 17); cJSON_AddItemToObject(pRoot, "value", pValue); //数组初始化 int hex[5] = {11, 12, 13, 14, 15}; cJSON *pHex = cJSON_CreateIntArray(hex, 5); //创建一个长度为5的int型的数组json元素 cJSON_AddItemToObject(pRoot, "hex", pHex); //将数组元素添加进pRoot char *s = cJSON_Print(pRoot); iot_debug_print("[cJSON_Test] creatJson:%s", s); //释放内存 cJSON_free((void *)s); //释放内存 //cJSON_Delete(pHex); //释放内存 //cJSON_Delete(pValue); //释放内存 cJSON_Delete(pRoot); iot_debug_print("[cJSON_Test] cJSON_Generate Stop"); ``` # 三、编译并下载程序 完整代码在这,自取。 ```c /* * @Author: your name * @Date: 2020-05-19 14:05:32 * @LastEditTime: 2020-06-15 00:10:00 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: \RDA8910_CSDK\USER\user_main.c */ #include "string.h" //#include "cs_types.h" #include "osi_log.h" #include "osi_api.h" #include "am_openat.h" #include "am_openat_vat.h" #include "am_openat_common.h" #include "iot_debug.h" #include "iot_uart.h" #include "iot_os.h" #include "iot_gpio.h" #include "iot_pmd.h" #include "iot_adc.h" #include "iot_vat.h" #include "iot_network.h" #include "iot_socket.h" #include "cJSON.h" //#include "MQTTClient.h" HANDLE TestTask_HANDLE = NULL; #define jsonRoot "{\r\n" \ "\"imei\": \"8661111111111111\",\r\n" \ "\"Num\": 142,\r\n" \ "\"Value\": {\r\n" \ "\"name\": \"cx\",\r\n" \ "\"age\": 18,\r\n" \ "\"blog\": \"https://blog.csdn.net/weixin_44570083/article/details/104285283\"\r\n" \ "},\r\n" \ "\"hexArry\": [31, 56, 36, 1365, 263]\r\n" \ "}\r\n" //JSON解析 void cJSON_Parsing() { // jsonRoot 是您要剖析的数据 //首先整体判断是否为一个json格式的数据 iot_debug_print("[cJSON_Test] cJSON_Parsing Start"); cJSON *pJsonRoot = cJSON_Parse(jsonRoot); //如果是否json格式数据 if (pJsonRoot != NULL) { iot_debug_print("[cJSON_Test] cJSON TRUE"); iot_debug_print("[cJSON_Test] cJSON:%s", jsonRoot); } else { iot_debug_print("[cJSON_Test] cJSON ERROR"); } //解析imei字段字符串内容 cJSON *pimeiAdress = cJSON_GetObjectItem(pJsonRoot, "imei"); //判断imei字段是否json格式 if (pimeiAdress) { //判断mac字段是否string类型 if (cJSON_IsString(pimeiAdress)) iot_debug_print("[cJSON_Test] get imeiAdress:%s", pimeiAdress->valuestring); } else iot_debug_print("[cJSON_Test] get imeiAdress failed"); //解析Num字段int内容 cJSON *pNumber = cJSON_GetObjectItem(pJsonRoot, "Num"); //判断Num字段是否存在 if (pNumber) { //判断mac字段是否数字整型类型 if (cJSON_IsNumber(pNumber)) iot_debug_print("[cJSON_Test] get Num:%d", pNumber->valueint); } else iot_debug_print("[cJSON_Test] get Num failed"); //解析value字段内容,判断是否为json cJSON *pValue = cJSON_GetObjectItem(pJsonRoot, "Value"); if (pValue) { //进一步剖析里面的name字段:注意这个根节点是 pValue cJSON *pName = cJSON_GetObjectItem(pValue, "name"); if (pName) { if (cJSON_IsString(pName)) iot_debug_print("[cJSON_Test] get value->Name:%s", pName->valuestring); } else iot_debug_print("[cJSON_Test] get pValue->pName failed"); //进一步剖析里面的age字段:注意这个根节点是 pValue cJSON *pAge = cJSON_GetObjectItem(pValue, "age"); if (pAge) { if (cJSON_IsNumber(pAge)) iot_debug_print("[cJSON_Test] get value->Age:%d", pAge->valueint); } else iot_debug_print("[cJSON_Test] get pValue->pAge failed"); //进一步剖析里面的blog字段:注意这个根节点是 pValue cJSON *pBlog = cJSON_GetObjectItem(pValue, "blog"); if (pBlog) { if (cJSON_IsString(pBlog)) iot_debug_print("[cJSON_Test] get value->pBlog:%s", pBlog->valuestring); } else iot_debug_print("[cJSON_Test] get pValue->pBlog failed"); } else iot_debug_print("[cJSON_Test] get pValue failed"); //剖析数组 cJSON *pArry = cJSON_GetObjectItem(pJsonRoot, "hexArry"); if (pArry) { //获取数组长度 int arryLength = cJSON_GetArraySize(pArry); iot_debug_print("[cJSON_Test] get arryLength:%d", arryLength); //逐个打印 int i; for (i = 0; i < arryLength; i++) iot_debug_print("[cJSON_Test] get cJSON_GetArrayItem(pArry, %d)= %d", i, cJSON_GetArrayItem(pArry, i)->valueint); } else iot_debug_print("[cJSON_Test] get pArry failed"); //释放内存 cJSON_Delete(pJsonRoot); iot_debug_print("[cJSON_Test] cJSON_Parsing Stop"); } //JSON生成 void cJSON_Generate() { //取一下本地的station的mac地址,保存在全局变量tempMessage iot_debug_print("[cJSON_Test] cJSON_Generate Start"); cJSON *pRoot = cJSON_CreateObject(); //新增一个字段imei到根点,数值是tempMessage char tempMessage[] = "8661111111111111"; cJSON_AddStringToObject(pRoot, "imei", tempMessage); //新增一个字段number到根点,数值是2 cJSON_AddNumberToObject(pRoot, "number", 2020); cJSON *pValue = cJSON_CreateObject(); cJSON_AddStringToObject(pValue, "name", "cx"); cJSON_AddNumberToObject(pValue, "age", 17); cJSON_AddItemToObject(pRoot, "value", pValue); //数组初始化 int hex[5] = {11, 12, 13, 14, 15}; cJSON *pHex = cJSON_CreateIntArray(hex, 5); //创建一个长度为5的int型的数组json元素 cJSON_AddItemToObject(pRoot, "hex", pHex); //将数组元素添加进pRoot char *s = cJSON_Print(pRoot); iot_debug_print("[cJSON_Test] creatJson:%s", s); //释放内存 cJSON_free((void *)s); //释放内存 //cJSON_Delete(pHex); //释放内存 //cJSON_Delete(pValue); //释放内存 cJSON_Delete(pRoot); iot_debug_print("[cJSON_Test] cJSON_Generate Stop"); } //main函数 int appimg_enter(void *param) { //系统休眠 iot_os_sleep(20000); cJSON_Parsing(); cJSON_Generate(); return 0; } //退出提示 void appimg_exit(void) { OSI_LOGI(0, "application image exit"); } ``` # 四、分析结果 查看输出的日志信息,可以看到JSON的解析与生成都是正确的。 ```c [00:11:49.559] [59599] [ 7216] [ ] [ ] [ ] OPEN/ : [cJSON_Test] cJSON_Parsing Start [00:11:49.559] [59603] [ 7217] [ ] [ ] [ ] OPEN/ : [cJSON_Test] cJSON TRUE [00:11:49.559] [59604] [ 7218] [ ] [ ] [ ] OPEN/ : [cJSON_Test] cJSON:{ "imei": "8661111111111111", "Num": 142, "Value": { "name": "cx", "age": 18, "blog": "https://blog.csdn.net/weixin_44570083/article/details/104285283" }, "hexArry": [31, 56, 36, 1365, 263] } [00:11:49.559] [59605] [ 7219] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get imeiAdress:8661111111111111 [00:11:49.559] [59606] [ 7220] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get Num:142 [00:11:49.559] [59606] [ 7221] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get value->Name:cx [00:11:49.559] [59606] [ 7222] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get value->Age:18 [00:11:49.559] [59607] [ 7223] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get value->pBlog:https://blog.csdn.net/weixin_44570083/article/details/104285283 [00:11:49.559] [59607] [ 7224] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get arryLength:5 [00:11:49.559] [59608] [ 7225] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get cJSON_GetArrayItem(pArry, 0)= 31 [00:11:49.559] [59608] [ 7226] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get cJSON_GetArrayItem(pArry, 1)= 56 [00:11:49.559] [59608] [ 7227] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get cJSON_GetArrayItem(pArry, 2)= 36 [00:11:49.559] [59608] [ 7228] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get cJSON_GetArrayItem(pArry, 3)= 1365 [00:11:49.559] [59609] [ 7229] [ ] [ ] [ ] OPEN/ : [cJSON_Test] get cJSON_GetArrayItem(pArry, 4)= 263 [00:11:49.559] [59609] [ 7230] [ ] [ ] [ ] OPEN/ : [cJSON_Test] cJSON_Parsing Stop [00:11:49.559] [59610] [ 7231] [ ] [ ] [ ] OPEN/ : [cJSON_Test] cJSON_Generate Start [00:11:49.559] [59619] [ 7232] [ ] [ ] [ ] OPEN/ : [cJSON_Test] creatJson:{ "imei": "8661111111111111", "number": 2020, "value": { "name": "cx", "age": 17 }, "hex": [11, 12, 13, 14, 15] } [00:11:49.615] [59620] [ 7233] [ ] [ ] [ ] OPEN/ : [cJSON_Test] cJSON_Generate Stop ``` > 不会下载的[点击这里](https://blog.csdn.net/weixin_44570083/article/details/104285283),进去查看我的`RDA8910 CSDK二次开发入门教程`专题第一篇博文`1、RDA8910CSDK二次开发:环境搭建`里面讲了怎么下载 > 这里只是我的学习笔记,拿出来给大家分享,欢迎大家批评指正,本篇教程到此结束
发表于 2020-06-15 00:50
阅读 ( 6024 )
1 推荐
收藏
你可能感兴趣的文章
13、RDA8910CSDK二次开发:将你的代码藏起来----编译静态库
5394 浏览
1.1、RDA8910CSDK二次开发:CSDK极致开发体验
7721 浏览
11、RDA8910CSDK二次开发:新鲜出炉的MQTT库
7859 浏览
10、RDA8910CSDK二次开发:简易的http通讯库
1808 浏览
9、RDA8910CSDK二次开发:趁热打铁干脆顺带把UDP通讯也给撸了吧
1849 浏览
相关问题
EVB_Air720UG_A12测试sdcard失败
0 回答
AIR724UG 固件下载失败
2 回答
合宙Air724UG的USB驱动问题
1 回答
0 条评论
请先
登录
后评论
陈夏
26 篇文章
作家榜
»
技术销售Delectate
43 文章
陈夏
26 文章
国梁
24 文章
miuser
21 文章
晨旭
20 文章
朱天华
19 文章
金艺
19 文章
杨奉武
18 文章
×
发送私信
发给:
内容:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!