• Jansson-STM32


    STM32处理json字符串一般不常见,大部分都是不需要处理的数据,但是在一些通信中需要处理上传或者下传的数据,就别比如在物联网中,有一部分数据就是以json格式传输的,那么就需要对数据经行解析。我简单记录一下我自己在STM32F103RC中使用jansson库的一些注意事项和出现的错误

    今天来了解一下一个和cJSON非常类似的解析库——Jansson的使用,支持解析和构建JSON字符串,不需要动态分配内存,使用方法和cJSON几乎一样。

    1、Json简介

    一、JSON:JavaScript Object Notation的简写,是一种轻量级数据交换格式。
    二、数据类型:标量、序列(数组)、映射(key-value)
    
    三、JSON的四个原则
     1 、并列数据之间用逗号隔开
     2、 映射用冒号:来表示
     3 、并列数据的集合用中括号[]来表示
     4、 映射的集合用大括号{}来表示
     如下形式:
     {"name": "John Doe",
     "age": 18, 
     "address": {
                "country" : "china", 
                "zip-code": "10000"
                }
     }
    四、JSON的优点
    1、 数据格式比较简单,格式是压缩的,占用带宽小 
    2、 支持Python等服务器端语言,便于服务器解析

    2、jansson库的下载安装和报错解决

    Jansson官网:http://jansson.readthedocs.io/en/latest/

    Jansson API文档:http://jansson.readthedocs.io/en/latest/apiref.html
    关于Jansson库的更多使用请查看官方文档。

    2.1、下载安装

      jansson库是有Keil版本的官方的,可以直接在官网下载,官网链接,下载安装就可以使用了,但是还会遇到其它问题。记录一下我自己的问题。

    在这里插入图片描述
    在这里插入图片描述
    下载下来的文件:
    在这里插入图片描述

    2.2、STM32工程文件中导入jansson库

    打开自己的工程文件,我自己使用的是正点原子的工程文件。

    在这里插入图片描述
    按照下面的顺序选择,就能看到第4布那个了,说明库文件已经添加成功。
    在这里插入图片描述

    2.3、报错解决

    添加了库函数之后出现如下报错,经过一番查找,终于找到了原因并且解决了。
    在这里插入图片描述
    对于报错,…OBJJansson_Test.axf: Error: L6915E: Library reports error: __use_no_semihosting was requested, but _ttywrch was referenced。
    在usart.c串口通信文件之中添加如下所示代码即可。
    在这里插入图片描述

    添加代码:

    //__use_no_semihosting was requested, but _ttywrch was 
    void _ttywrch(int ch)
    {
    ch = ch;
    }

    对于报错,…OBJJansson_Test.axf: Error: L6915E: Library reports error: __use_no_semihosting was requested, but _sys_open was referenced。
    勾选Use MicroLIB 。
    在这里插入图片描述

    2.4、修改堆栈空间

    修改启动文件里面的堆栈范围,防止在程序运行过程中空间不足出现死机。
    在这里插入图片描述

    3、Json 字符的创建

    //jansson Test
    void jansson_pack_test(void)
    {
        json_t *root; // json_t用于引用任何JSON节点
        char *out;
        
        /* Build an empty JSON object */
        root = json_pack("{}");
        
        out = json_dumps(root, JSON_ENCODE_ANY);
        printf("out:%s
    ", out);
        json_delete(root);
        free(out);
        
        /* Build the JSON object {"foo": 42, "bar": 7} */
        root = json_pack("{sisi}", "foo", 42, "bar", 7);
        out = json_dumps(root, JSON_ENCODE_ANY);
        printf("out:%s
    ", out);
        json_delete(root);
        free(out);
        
        /* Like above, ':', ',' and whitespace are ignored */
        root = json_pack("{s:i, s:i}", "foo", 42, "bar", 7);
        out = json_dumps(root, JSON_ENCODE_ANY);
        printf("out:%s
    ", out);
        json_delete(root);    
        free(out);
        
        /* Build the JSON array [[1, 2], {"cool": true}] */
        root = json_pack("[[i,i],{s:b}]", 1, 2, "cool", 1);
        out = json_dumps(root, JSON_ENCODE_ANY);
        printf("out:%s
    ", out);
        json_delete(root);
        free(out);
        
        /* Build a string from a non-null terminated buffer */
        char buffer[4] = {'t', 'e', 's', 't'};
        root = json_pack("[s#]", buffer, 4);
        out = json_dumps(root, JSON_ENCODE_ANY);
        printf("out:%s
    ", out);
        json_delete(root);
        free(out);
        
        /* Concatenate strings together to build the JSON string "foobarbaz" */
        root = json_pack("[s++]", "foo", "bar", "baz");
        out = json_dumps(root, JSON_ENCODE_ANY);
        printf("out:%s
    ", out);
        json_delete(root);//不要用free,用free()会导致Heap溢出
        //free(root);
        free(out);
    }

    输出结果;
    在这里插入图片描述
    其中要特别注意到,json_delete()和free()函数的使用,json_delete()函数可以清空json_t格式的内存,json_t格式使用 free()函数是无法清空,但是free()函数可以清空非json_t格式的。如下图所示:
    在这里插入图片描述
    在这里插入图片描述

    4、Json 字符的解析

    代码来源:https://blog.csdn.net/whik1194/article/details/106872260?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-3

    4.1 纯键值对

    //纯键值对
    {
    "status":true,
    "age":20,
    "Score":88.9,
    "name":"CQS",
    "blog":"https://blog.csdn.net/weixin_45488643",
    "wechat":"QingYeMuRong"
    }
    uint8_t Jansson_Key(void)   //纯键值对
    {
        const char *text = "{"status":true,"age":20,"score":88.88,"name":"CQS","blog":"https://blog.csdn.net/weixin_45488643","wechat":"QingYeMuRong"}";
        
        json_error_t error;
        json_t *root;
        json_t *status;
        char *name, *blog, *wechat;
        int age;
        double score;
        
        root = json_loads((const char*)text, 0, &error); 
        if(json_is_object(root))   // 如果读取失败,自动置为空指针
        {
            
            /* string 类型的解析 */
            name = (char *)json_string_value(json_object_get(root, "name"));
            blog = (char *)json_string_value(json_object_get(root, "blog"));
            wechat = (char *)json_string_value(json_object_get(root, "wechat"));
            
            printf("name: %s
    ", name);
            printf("blog: %s
    ", blog);
            printf("wechat: %s
    ", wechat);
            
            /* int 类型的解析 */
            age = json_integer_value(json_object_get(root, "age"));
            printf("age: %d
    ", age);
            
            /* double 类型的解析 */
            score = json_real_value(json_object_get(root, "score"));
            printf("score: %.1f
    ", score);
            
            /* bool 类型的解析 */
            status = json_object_get(root, "status");
            if(json_is_true(status))
                printf("status: true
    ");
            else if(json_is_false(status))
                printf("status: false
    ");
        }
        else
        {
            printf("root format error:%d-%s
    ", error.line, error.text);
            return 1;
        }
        return 0;
    }   

    输出结果:
    在这里插入图片描述

    4.2、键的值是一个对象

    //键的值是一个对象
    {
        "success": "1",
        "result": {
            "timestamp": "12345678900",
            "datetime_1": "2020-07-04 16:04:09",
            "week_1": "6",
            "week_2": "Saturday"
        }
    }
    uint8_t Jansson_Object(void)  //键的值是一个对象
    {
        const char *text = "{"success":"1","result":{"timestamp":"12345678900","datetime_1":"2020-07-04 16:04:09","week_1":"6","week_2":"Saturday"}}";
        json_error_t error;
        json_t *root;
        json_t *result;
        
        char *success;
        char *timestamp;
        char *datetime_1;
        char *week_1;
    
        root = json_loads((const char*)text, 0, &error); 
        if(json_is_object(root))
        {
            printf("root format correct
    ");
            success = (char *)json_string_value(json_object_get(root, "success"));
            printf("success:%s
    ", success);
            
            result = json_object_get(root, "result");
            if(json_is_object(result))
            {
                timestamp = (char *)json_string_value(json_object_get(result, "timestamp"));
                datetime_1 = (char *)json_string_value(json_object_get(result, "datetime_1"));
                week_1 = (char *)json_string_value(json_object_get(result, "week_1"));
                
                printf("timestamp:%s
    ", timestamp);
                printf("datetime_1:%s
    ", datetime_1);
                printf("week_1:%s
    ", week_1);
            }
            else 
            {
                printf("reuslt format error
    ");
                return 1;
            }
        }
        else
        {
            printf("root format error:%d-%s
    ", error.line, error.text);
            return 1;
        }
        return 0;
    }

    输出结果:
    在这里插入图片描述

    4.3、键的值是一个数组

    {
        "location": [{
            "name": "Faye",
            "address": "Tianjing"
        }, {
            "name": "Andy",
            "address": "XinJiab"
        }, {
            "name": "Lisa",
            "address": "WuLu"
        }],
        "time": "2020-07-04"
    }
    ```c
    uint8_t Jansson_Array (void)  //键的值是一个数组
    {
        const char *text = "{"location":[{"name":"Faye","address":"Beijing"},{"name":"Andy","address":"ShangHai"},{"name":"Lisa","address":"ShenZhen"}],"time":"2020-07-04"}";
       
        json_error_t error;
        json_t *root;
        json_t *location_arr;
        json_t *location;
        
        char *name, *address;
        char *time;
        int idx;
        
        root = json_loads((const char*)text, 0, &error); 
        if(json_is_object(root))
        {
            printf("root format correct
    ");
            time = (char *)json_string_value(json_object_get(root, "time"));
            location_arr = json_object_get(root, "location");
            if(json_is_array(location_arr))
            {
                for(idx = 0; idx < json_array_size(location_arr); idx++)
                {
                    location = json_array_get(location_arr, idx);
                    name = (char *)json_string_value(json_object_get(location, "name"));
                    address = (char *)json_string_value(json_object_get(location, "address"));
                    printf("%d: %s-%s
    ", idx, name, address);
                }
            }
        }
        else
        {
            printf("root format error:%d-%s
    ", error.line, error.text);
            return 1;
        }
        return 0;
    }

     附上下载链接:https://wwa.lanzous.com/b00npy6dc密码:201k

    参考文章:https://blog.csdn.net/weixin_45488643/article/details/107132066?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-6.control

  • 相关阅读:
    求n(n>=2)以内的质数/判断一个数是否质数——方法+细节优化
    poj1185炮兵阵地 正确代码及错误代码分析
    运算符优先级的几点注意
    mod(%)之规律(除数与被除数的正负分析)
    css背景
    Content-Type
    vue数组的增改和v-model的绑定使用Demo
    python open函数关于w+ r+ 读写操作的理解(转)
    http状态码解释
    cookie与token对比(转)
  • 原文地址:https://www.cnblogs.com/fw-qql/p/14326462.html
Copyright © 2020-2023  润新知