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

原文地址:https://www.cnblogs.com/fw-qql/p/14326462.html