嵌入式json:jansson应用(1)

日常工作/学习中难免会遇到嵌入式设备与服务器交互的场景,通讯协议上基本以下几种

 

1.自定义字符,包头包尾

2.xml

3.json

第一种的话虽然程序写起来简单,但是存在 通用性差,而且出现问题,抓包时还要对照协议导致排查效率低下。

而第3种json,考虑到服务器大部分都是java spring应用,用阿里的fastjson库直接就可以构建出java实体类,所以嵌入式这边使用json来交互,对web后端开发人员更加友好。

所以今天就来研究研究json作为通讯协议的嵌入式应用。

我们用的json库是jansson,因为嵌入式这边,特别是在mcu上,资源紧缺啊,所以只能上一些优化过的库。

1.keil添加jansson

这个很简单,网上资源有很多,这边稍微带一下吧

然后就可以看到,lib和C文件添加进来了,这样环境就搭建好了

 

使用是,记得加个头文件即可

#include <string.h>
#include <jansson.h>

2.使用

我们使用json,无非2个需求:

发包和解包:把自己的数据打包以json格式发出去 

                      把服务器(别人的)包接受进来,解析出相应的数字/数组/字符串/对象

jansson的API特比的丰富,,类型如下

JSON_OBJECT
JSON_ARRAY
JSON_STRING
JSON_INTEGER
JSON_REAL
JSON_TRUE
JSON_FALSE
JSON_NULL

当我们得到一个 json_t的数据结构,可以用判断其类型,例如判断出是字符串,接下来可以用

json_string_value(val)得到其数据,如果是integer类型的话,也一样,用json_is_integer(val)来判断,用json_integer_value(val)得到其数据

json_typeof(const json_t *json)

int json_is_object(const json_t *json)
int json_is_array(const json_t *json)
int json_is_string(const json_t *json)
int json_is_integer(const json_t *json)
int json_is_real(const json_t *json)
int json_is_true(const json_t *json)
int json_is_false(const json_t *json)
int json_is_null(const json_t *json)

2.1发包

对于业务来讲,json打包除了字符串,还有特殊的数组,对象等,这边给一个例子,这些类型在里面都有示例

代码:

void json()
{
	
    json_t* myjson = NULL;
    json_t* item = NULL;
    json_t* array = NULL;	

	
    myjson  = json_object();
    item  = json_object();
    array = json_array();
 
    char* str = NULL;
 
    json_array_append(array,json_integer(21));
    json_array_append(array,json_integer(128));
    json_array_append(array,json_integer(0));
    json_array_append(array,json_integer(128));
	
    json_object_set_new(item,"heartbeat",json_string("on"));
    json_object_set_new(item,"id",json_integer(21));
    json_object_set_new(item,"true",json_true());
    json_object_set_new(item,"false",json_false());
    json_object_set_new(item,"json_real",json_real(12.987));
    json_object_set_new(myjson,"distance",array);
    json_object_set_new(myjson,"mything",item);
 
 
    str = json_dumps(myjson, JSON_INDENT(0));
    printf("str = %s \n",str);
    free(str);
 
    json_decref(myjson);
}

打印结果

{
    "distance": [
        21,
        128,
        0,
        128
    ],
    "mything": {
        "heartbeat": "on",
        "id": 21,
        "true": true,
        "json_real": 12.987,
        "false": false
    }
}

这个例子中可以看出,核心数据对象是json_t,

json_decref函数用于销毁构建json过程中申请的内存,不然存在 内存泄漏的风险。

json_dumps是打印函数,将json_t转换为字符串,其第二个形参决定了打印的格式,工作中常用的JSON_INDENT,JSON_COMPACT,JSON_PRESERVE_ORDER参数在json_pack函数的时候会提到。

2.2解包

对服务器过来的json数据进行解包,这个过程中如果可以的话,最好对解包后的数据做层校对,这样是最好了,这边同样给个例子,覆盖大部分业务场景用到的数据类型

void json_parse(){
	 char *strbuf="{\"distance\":[21, 128, 0, 128], \"mything\": {\"heartbeat\": \"on\", 
                    \"id\": 21, \"true\": true, \"json_real\": 12.987, \"false\": 
                     false}}";
  
	json_error_t err;
	char* str = NULL;
	json_t* myjson = json_loads(strbuf, 0, &err);
	
    
    if(NULL != myjson && json_is_object(myjson))
	{
			json_t* disancearray= json_object_get(myjson, "distance");
			if(NULL != disancearray && json_is_array(disancearray))
			{
				  size_t index;
				  json_t *value;
                  json_array_foreach(disancearray, index, value) {
                  /* block of code that uses index and value */
				  printf("%d:%d\r\n",index,(int)json_integer_value(value));
            }
	}
	json_t* mything= json_object_get(myjson, "mything");
	if(NULL != mything && json_is_object(mything))
	{
			json_t* heartbeat= json_object_get(mything, "heartbeat");
			if(NULL != heartbeat && json_is_string(heartbeat)){
						printf("heartbeat:%s\r\n",json_string_value(heartbeat));
			}
			json_t* id= json_object_get(mything, "id");
			if(NULL != heartbeat && json_is_integer(id)){
						printf("id:%d\r\n",(int)json_integer_value(id));
			}
			json_t* true= json_object_get(mything, "true");
			if(NULL != heartbeat && json_is_true(true)){
						printf("true:%d\r\n",json_is_true(true));
			}
			json_t* json_real= json_object_get(mything, "json_real");
			if(NULL != heartbeat && json_is_real(json_real)){
						printf("true:%f\r\n",json_real_value(json_real));
			}
			json_t* false= json_object_get(mything, "false");
			if(NULL != heartbeat && json_is_false(false)){
			    		printf("false:%d\r\n",json_is_false(false));
			}
	}
}

		json_decref(myjson);
}

打印结果

0:21
1:128
2:0
3:128
heartbeat:on
id:21
true:1
true:12.987000
false:1

这段代码的话,json_loads函数比较重要,将字符串转换为json_t数据结构体,其取值过程基本类似,都是先判断一下是否是null,类型是否正确,然后用该类型的取值函数取值.

如果止步于此,就不是jansson了,下一章节,给大家介绍json_pack和json_unpack两个神兵利器

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值