cJson 库的使用

作者: 苏丙榅

链接: cJson 库的使用 | 爱编程的大丙 (subingwen.cn)
来源: 爱编程的大丙
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

cJson库在stm32上的移植及相关动态内存的分配和释放请看野火B站教程13分49秒:第21章-MQTT协议3_哔哩哔哩_bilibili 

视频来源:野火 LwIP视频教学 配套书籍《LwIP应用开发实战指南》 配套源码 基于STM32 以太网教学 网络教学视频  著作权归作者所有。

实际运用中添加了cJSON库很可能编译不过,需要设置STM32的堆栈内存大小(调小一些就可以编译通过),这里没有一个建议值,需要根据整个项目需要用到的堆栈大小进行分配。堆原来为0xa000=40960;调整太小也可能导致堆栈溢出,程序跑飞或死机。

堆栈设置可以参考博客:(28条消息) STM32堆栈空间大小设置_智小星的博客-CSDN博客_stm32堆栈大小     

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

                      

                          常见JSON格式请求示例

一、请求参数

{  
  "deviceno":"12345678",
        "data":{
              "cardd":"7000",
              "Type":5,
              "Time":"2023-05-30 14:15:16",
              "checkMode":0
              }
}

如果请求参数如上:示例如下:

void send_test_num(void)
{
    // 创建JSON对象
    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "deviceno", "12345678");

    cJSON *data = cJSON_CreateObject();
    cJSON_AddStringToObject(data, "card", "7000");
    cJSON_AddNumberToObject(data, "Type", 5);
    cJSON_AddStringToObject(data, "Time", "2023-05-30 14:15:16");
    cJSON_AddNumberToObject(data, "Mode", 0);

    cJSON_AddItemToObject(root, "data", data);

    char* parmas=cJSON_Print(root);

    memset(url,0x0,sizeof(url));
    getFullUrl("xiaogeng/test/api/sendvalue",url,sizeof(url));
    log_info("Send_Token,url:xiaogeng/test/api/sendvalue");
    string* responseStr = post(url, parmas,usrcfg->Timeout);

    cJSON_free(parmas);//需要释放
    cJSON_Delete(root);//需要释放
    //cJSON_Delete(data);//不能释放,否则会有问题,像这种包含在root里面的只需要释放最外层即可,如果要验证可以在释放root后打印data的值看看是不是没有了

    if (responseStr) {
        log_info("receive http msg test:%s\n",responseStr->ptr);
        unsigned char response=Parse_Test_num(responseStr->ptr);
        free(responseStr->ptr);
        responseStr->ptr=NULL;
        free(responseStr);
        responseStr=NULL;

        return response;
    }
    return 0;
}

二、响应参数如下,则示例代码如下

unsigned char Pars_test(const char *content)
{
    int code = 0;
    int version = 0;
    cJSON *root = cJSON_Parse(content);
    if (!root)
    {
        return 0;
    }
    int ret = getKeyValueInt(root,"code",&code);
    
    if(code == 0){
        cJSON *jsonmap = cJSON_GetObjectItem(root,"data");//注意这个不用释放---------如果释放会报指针错误-------程序崩溃,释放最外层root即可
        if(jsonmap)
        {
            getKeyValueInt(jsonmap,"version",&version);
          
            memset(savecfg,0,sizeof(savecfg));
            sprintf(savecfg,"{\"version\":%d}",version);
            cJSON *roottmp = cJSON_Parse(savecfg);
            if(roottmp){
               //{“version”:1}
                cJSON_Delete(roottmp);//需要释放
            } 
        } 
    }
    cJSON_Delete(root);//需要释放
    return version;
}

三、如下是一些常用转换

/**
 * @brief cJSON获取int值
 * 
 * @param root cJSON
 * @param key Key值
 * @param _dest int指针
 * @return u8 获取成功返回8,类型不是int返回-8,key不存在返回0
 */
int getKeyValueInt(cJSON *root,const char *key, int *_dest)
{
    if (isHasKey(root, key))
    {
        if(cJSON_GetObjectItem(root, key)->type == cJSON_Number)
        {
            *_dest=cJSON_GetObjectItem(root, key)->valueint;
            return 8;
        }
        else
        {
            return -8;
        }
    }
    else
    {
        return 0;
    }
}
/**
 * @brief cJSON获取int值(Key类型是任意的)
 * 
 * @param root cJSON
 * @param key Key值
 * @param _dest int指针
 * @return u8 key是按int获取的则返回8,按string获取的返回16,类型错误的返回-1,key不存在返回0
 */
int getKeyValueAuto(cJSON *root,const char *key, int *_dest)
{
    if (isHasKey(root, key))
    {
        if(cJSON_GetObjectItem(root, key)->type == cJSON_Number)
        {
            //strcpysafe(_dest,cJSON_GetObjectItem(root, key)->valuestring,_destSizeof);
            *_dest=cJSON_GetObjectItem(root, key)->valueint;
            return 8;
        }
        else if(cJSON_GetObjectItem(root, key)->type == cJSON_String)
        {
            *_dest=atoi(cJSON_GetObjectItem(root, key)->valuestring);
            return 16;
        }
        else if(cJSON_GetObjectItem(root, key)->type == cJSON_True)
        {
            *_dest=1;
            return 1;
        }
        else if(cJSON_GetObjectItem(root, key)->type == cJSON_False)
        {
            *_dest=0;
            return 1;
        }
        else
        {
            return -1;
        }
    }
    else
    {
        return 0;
    }
}
/**
 * @brief cJSON获取Double值(Double是八字节,long是四字节,long long是八字节)
 * 
 * @param root cJSON
 * @param key Key值
 * @param _dest long指针
 * @return u8 获取成功返回8,类型不是Number返回-8,key不存在返回0
 */
int getKeyValueDouble(cJSON *root,const char *key, double *_dest)
{
    if (isHasKey(root, key))
    {
        if(cJSON_GetObjectItem(root, key)->type == cJSON_Number)
        {
            *_dest=cJSON_GetObjectItem(root, key)->valuedouble;
            return 8;
        }
        else
        {
            return -8;
        }
    }
    else
    {
        return 0;
    }
}
/**
 * @brief cJSON获取字符串
 * 
 * @param root cJSON
 * @param key Key值
 * @param _dest 目标数组
 * @param _destSizeof 目标数组长度,可输入sizeof(_dest)
 * @return u8 获取成功返回16,类型不是String返回-16,key不存在返回0
 */
int getKeyValueString(cJSON *root, const char *key, char *_dest, size_t _destSizeof)
{
    if (isHasKey(root, key))
    {
        if(cJSON_GetObjectItem(root, key)->type == cJSON_String)
        {
            memset(_dest,0x0,_destSizeof);
            strcpysafe(_dest,cJSON_GetObjectItem(root, key)->valuestring,_destSizeof);
            return 16;
        }
        else
        {
            return -16;
        }
    }
    else
    {
        return 0;
    }
}

 四、数组相关操作

              if (isHasKey(jsonmap2, "cards")){
                        cJSON *myEmparray = cJSON_CreateArray();//转换为我们下发白名单格式字符串
                        int count = cJSON_GetArraySize(cJSON_GetObjectItem(jsonmap2,"cards"));//卡号数组    可以获取到数组有多少个元素
                        for (int i = 0; i < count; i++)
                        {
                            cJSON *item = cJSON_GetArrayItem(cJSON_GetObjectItem(jsonmap2,"cards"), i);    //获取每个数组元素的值
                            if(item){
                                cJSON *objId = cJSON_CreateObject();
                                
                                u8 card[20]={0x0},userId[20]={0x0},tmpbuf[20]={0x0};
                                getKeyValueString(item,"card",card,sizeof(card));
                                //getKeyValueString(item,"userId",userId,sizeof(userId)); //由于userId只是预留,因此employeeid改为卡号+Floor值
                                sprintf(userId,"%s2",card);

                                //{"EmployeeId":"1001","Name":"张三","Number":"Cerb01","ICCard":"999985","QRCard":"18012345678","StartTime":"2020-01-01 00:01:01","EndTime":"2049-12-30 23:59:59","DeleteFlag":"0","Times":0}
                                cJSON_AddStringToObject(objId, "EmployeeId", userId);
                                cJSON_AddStringToObject(objId, "Name", "");
                                cJSON_AddStringToObject(objId, "Number", hourInterval_str);//Number用于存在时段
                                cJSON_AddStringToObject(objId, "ICCard", card);
                                //cJSON_AddStringToObject(objId, "QRCard", card);
                                cJSON_AddStringToObject(objId, "StartTime", "2018-01-01 01:01:01");
                                cJSON_AddStringToObject(objId, "EndTime", dateEnd);
                                cJSON_AddStringToObject(objId, "DeleteFlag", itoa(type_str,tmpbuf,10));
                                cJSON_AddNumberToObject(objId, "Times", 0);
                                cJSON_AddStringToObject(objId, "Floor", "2");

                                cJSON_AddItemToArray(myEmparray, objId);
                            }
                        }
                        char *pStr = cJSON_Print(myEmparray);
                        printf("my emp json:%s\n",pStr);
                        cJSON_free(pStr);
                        //调用标准版的白名单插入函数。先检查格式是否正确
                        ArrayItemEmpsToDB(myEmparray,CONFIGTYPE_T,NULL);

                        cJSON_Delete(myEmparray);

                    }

 

posted @ 2022-08-31 20:19  耿通宇  阅读(154)  评论(0编辑  收藏  举报