STM32使用 jansson 处理 Json格式字符


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

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、报错解决

添加了库函数之后出现如下报错,经过一番查找,终于找到了原因并且解决了。
在这里插入图片描述
对于报错,…\OBJ\Jansson_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;
}

对于报错,…\OBJ\Jansson_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\r\n", 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\r\n", 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\r\n", 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\r\n", 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\r\n", 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\r\n", 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\r\n", name);
        printf("blog: %s\r\n", blog);
        printf("wechat: %s\r\n", wechat);
        
        /* int 类型的解析 */
        age = json_integer_value(json_object_get(root, "age"));
        printf("age: %d\r\n", age);
        
        /* double 类型的解析 */
        score = json_real_value(json_object_get(root, "score"));
        printf("score: %.1f\r\n", score);
        
        /* bool 类型的解析 */
        status = json_object_get(root, "status");
        if(json_is_true(status))
            printf("status: true\r\n");
        else if(json_is_false(status))
            printf("status: false\r\n");
    }
    else
    {
    
    
        printf("root format error:%d-%s\r\n", 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\r\n");
        success = (char *)json_string_value(json_object_get(root, "success"));
        printf("success:%s\r\n", 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\r\n", timestamp);
            printf("datetime_1:%s\r\n", datetime_1);
            printf("week_1:%s\r\n", week_1);
        }
        else 
        {
    
    
            printf("reuslt format error\r\n");
            return 1;
        }
    }
    else
    {
    
    
        printf("root format error:%d-%s\r\n", 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\r\n");
        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\r\n", idx, name, address);
            }
        }
    }
    else
    {
    
    
        printf("root format error:%d-%s\r\n", error.line, error.text);
        return 1;
    }
    return 0;
}

输出结果:
在这里插入图片描述
附上下载链接:https://wwa.lanzous.com/b00npy6dc密码:201k

猜你喜欢

转载自blog.csdn.net/weixin_45488643/article/details/107132066
今日推荐