cJSON库

作者:陈之敏 时间:2020年08月15日 关键字:csdk、RDA8910、二次开发、cJSON

目录

点击这里查看所有博文

  最近听说有的小伙伴看了我的教程后,有一些问题都跑到官方的gitee上面去问去了。导致官方的人没搞懂问的是啥,小伙伴们也没能知道自己想要的答案。给大家造成了困扰,这里我说声抱歉。

  既然出现了这个问题,我这里就声明一下,本系列教程所涉及的内容(demo)不是官方的作品。我个人觉得官方的demo内容太多太全,往往都是把一个模块内所有的东西全部放在一起。这样的话对新手不是很友好,阅读起来也比较费劲。我就把官方的部分demo进行相关的简化,并推出教程这样的话可能会对新手朋友们有一定的帮助。

  有时候周末闲暇时间我也会加上一些我觉得好玩的模块在里面,这些可能在官方的demo都没有,比如cJSON、PAHO-MQTT、http-client。

  这就是官方的代码仓库。

git clone --recursive https://gitee.com/openLuat/Luat_CSDK_Air724U.git

  当然各位小伙伴在看本教程时,我建议还是使用我下面提供的仓库比较好,看完之后在迁移到官方的仓库⇧。

git clone --recursive https://gitee.com/chenxiahuaxu/RDA8910_CSDK.git

  再看本教程过程中如果遇到了问题,可以在本人的代码仓库下面评论。也可以在本人的博客下面评论。我要是看到的话,并且这个问题在我的能力范围的话我会尽力解答的(非官方,不要对我要求太多哦,要求太多我可能就不管啦)。

一、前言

  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字符串的生成与解析

在这里插入图片描述   总之就是一句话。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 charvalue)

/**从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 charstring, cJSON *item);

/创建一个数组对象@param numbers:要创建的数组 @param ``count``:数组的长度@return 创建的对象 **/

  • CJSON_PUBLIC(cJSON ) ``cJSON_CreateIntArray``(const intnumbers, int count)

/将cJSON项目/实体/结构呈现为文本。@param item:cJSON对象 *@return 字符串 **/

  • CJSON_PUBLIC(char ) ``cJSON_Print``(const cJSONitem)

/释放内存@param object:要释放的内存块 **/

  • CJSON_PUBLIC(void) cJSON_free(void *object); ## 2.2、编写cJSON解析程序   解析程序负责将一个json格式的字符串转换成cJSON对象,并在其中查找需要的键值对。要注意的是,查找完毕后需要删除cJSON_Parse函数创建的父节点。

// 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

//取一下本地的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");

三、编译并下载程序

  完整代码在这,自取。

/*
 * @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的解析与生成都是正确的。

[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

不会下载的点击这里,进去查看我的RDA8910 CSDK二次开发入门教程专题第一篇博文1、RDA8910CSDK二次开发:环境搭建里面讲了怎么下载 这里只是我的学习笔记,拿出来给大家分享,欢迎大家批评指正,本篇教程到此结束