栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

linux C语言 libjson-c解析 JSON格式 生成JSON格式 API

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux C语言 libjson-c解析 JSON格式 生成JSON格式 API

前言:在linux下C语言项目中经常会使用到JSON格式,记录一次JSON格式的生成和解析 生成JSON格式,项目用来下发串口参数

json-c官方API文档

	int index = 0;
	char buff[1024] = {0};
	index += sprintf(buff + index, "{rn");
	index += sprintf(buff + index, ""serial_para":rn");
	index += sprintf(buff + index, "[rn");
	index += sprintf(buff + index, "{rn");
	index += sprintf(buff + index, ""device_name":"_/dev/ttyS3",rn");
	index += sprintf(buff + index, ""ip_addr":"10.20.1.83",rn");
	index += sprintf(buff + index, ""ip_port":9333,rn");
	index += sprintf(buff + index, ""speed":115200,rn");
	index += sprintf(buff + index, ""data_bit":8,rn");
	index += sprintf(buff + index, ""stop_bit":1,rn");
	index += sprintf(buff + index, ""parity":"N"rn");
	index += sprintf(buff + index, "},rn");
	index += sprintf(buff + index, "{rn");
	index += sprintf(buff + index, ""device_name":"_/dev/ttyS5",rn");
	index += sprintf(buff + index, ""ip_addr":"10.20.1.83",rn");
	index += sprintf(buff + index, ""ip_port":9555,rn");
	index += sprintf(buff + index, ""speed":115200,rn");
	index += sprintf(buff + index, ""data_bit":8,rn");
	index += sprintf(buff + index, ""stop_bit":1,rn");
	index += sprintf(buff + index, ""parity":"N"rn");
	index += sprintf(buff + index, "}rn");
	index += sprintf(buff + index, "]rn");
	index += sprintf(buff + index, "}rn");
	//以上代码段生成JSON格式的buff如下
	
	{
		serial_para:
		[
			{
				"device_name":"_/dev/ttyS3",
				"ip_addr":"10.20.1.83",
				"ip_port":9333,
				"speed":115200,
				"data_bit":8,
				"stop_bit":1,
				"parity":"N"
			},
			{
				"device_name":"_/dev/ttyS5",
				"ip_addr":"10.20.1.83",
				"ip_port":9335,
				"speed":115200,
				"data_bit":8,
				"stop_bit":1,
				"parity":"N"
			}
		]
	}
解析JSON格式
struct serial_para {
	char dev_name[16];
	char ip_addr[16];
	int ip_port;
	int speed;
	int databit;
	int stopbit;
	char parity[32];
};

int handle_json_data(char *buff) {
	int i = 0;
	int ret = 0;
	size_t array_cnt;
	char tmp[32] = {0};
	char msg[128] = {0};
	json_object *obj, *sub_obj;
	struct serial_para serial_info;

	//serial_info = (struct serial_para *)malloc(sizeof(struct serial_para));
	obj = sub_obj = NULL; 
	const char *ok_msg = {"{"status":"OK"}"};
	const char *err_msg1 = {"{"status":"Invalid JSON Format"}"};	
	const char *err_msg2 = {"{"status":"Invalid param"}"};

	obj = json_tokener_parse(buff);  
	if (obj == NULL) {
		strcpy(msg, err_msg1);
		log_info("client data Invalid JSON Format");
		return -1;
	}

	ret = json_object_object_get_ex(obj, "serial_para", &sub_obj); 
	if (ret != 1) {
		log_info("Fails to get params");
		strcpy(msg, err_msg2);
		return -1;
	}

	enum json_type type = json_object_get_type(sub_obj);   

	if(type == json_type_array) {
		array_cnt = json_object_array_length(sub_obj);  
		log_info("get json array success cnt = %d", array_cnt);	
	
		for(i = 0; i < array_cnt; i++) {
			json_object *array_obj = json_object_array_get_idx(sub_obj, i); 
	
			get_json_string(array_obj, "device_name", tmp);  
			strcpy(serial_info.dev_name, tmp);
			memset(tmp, 0, 32);
			
			get_json_string(array_obj, "ip_addr", tmp);
			strcpy(serial_info.ip_addr, tmp);
			memset(tmp, 0, 32);
			
			get_json_string(array_obj, "ip_port", tmp);
			serial_info.ip_port = atoi(tmp);
			memset(tmp, 0, 32);

			get_json_string(array_obj, "speed", tmp);
			serial_info.speed = atoi(tmp);
			memset(tmp, 0, 32);
			
			get_json_string(array_obj, "data_bit", tmp);
			serial_info.databit = atoi(tmp);
			memset(tmp, 0, 32);
			
			get_json_string(array_obj, "stop_bit", tmp);
			serial_info.stopbit = atoi(tmp);
			memset(tmp, 0, 32);
			
			get_json_string(array_obj, "parity", tmp);
			strcpy(serial_info.parity, tmp);
			memset(tmp, 0, 32);
			
			sys_serial2net(serial_info);
			memcpy(&serial_info_g[i], &serial_info, sizeof(struct serial_para));
			
			if (array_obj != NULL) {
				//json_object_put(array_obj);
			}
		}
	}
	
	if (obj != NULL) {
		//json_object_put(obj);
	}

	if (sub_obj != NULL) {
		//json_object_put(sub_obj);
	}
	
	strcpy(msg, ok_msg);
	return 0;
}
其中json_object_put全部注释掉了,因为发现任何一个json_object_put都会导致段错误,查看API文档后发现json_object_array_get_idx函数会释放这些变量的空间,当再次释放的时候就会导致double free的段错误。以下是官网API表述。

JSON_EXPORT int json_object_put ( 结构json_object * 对象 )
减少 json_object 的引用计数,如果达到零则释放。

在执行此操作之前,您必须拥有 obj 的所有权,否则会导致引用计数不平衡,从而导致经典的 use-after-free 错误。特别是,您通常不需要调用orjson_object_put()返回的 json_object 。json_object_object_get() 、json_object_array_get_idx()

就像在调用一块内存之后一样,在调用它或它所属的任何对象之后free(),你不能使用它(除非你知道你已经调用了显式增加引用计数)。objjson_object_put()json_object_get(obj)

NULL 可能会被传递,这种情况下这是一个空操作。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/947745.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号