简介:
struct2json 是一个开源的C结构体与 JSON 快速互转库,它可以快速实现 结构体对象 与 JSON 对象 之间序列化及反序列化要求。快速、简洁的 API 设计,大大降低直接使用 JSON 解析库来实现此类功能的代码复杂度。
我们在之前已经完成AT24C32 的驱动开发(AT24C32 EEPROM驱动适配),我们此基础上将JSON 的配置数据保存在EEPROM上作文配置项目来使用,struct2json 的一适配起来很简单,只需要简单的将源码文件加入工程,涉及的文件也不多,只有三个.C文件加入工程即可。
另外struct2json 依赖动态分配内存接口来申请和释放内存资源,本地使用的默认的malloc/free 函数进行内存管理。
我们把EEPROM 的1K空间划分为配置存储分区,使用如下的结构体来保存一个简单的配置信息。
typedef struct cfg { char cfg_name[10]; uint8_t status; } cfg_t;
本地编写测试代码序列化cjson,并将序列化后的数据写入后端的EEPROM空间里,编写如下测试代码将上述的结构体转换为cJSON对象后,并将数据写入EEPROM中。
cJSON * cfg_struct_to_json(void * pcfg) { struct cfg * cfg = (struct cfg *)pcfg; /* Create config json objject */ s2j_create_json_obj(json_cfg); /* Config json data */ s2j_json_set_basic_element(json_cfg,cfg,string,cfg_name); s2j_json_set_basic_element(json_cfg,cfg,int,status); return json_cfg; } unsigned int s2j(char argc,char *argv[]) { cJSON * led_json = NULL; static cfg_t led_cfg; led_cfg.cfg_name[0] = 'L'; led_cfg.cfg_name[1] = 'E'; led_cfg.cfg_name[2] = 'D'; led_cfg.cfg_name[3] = '\0'; led_cfg.status = 1; if(strcmp(argv[1],"encode") == 0) { led_json = cfg_struct_to_json(&led_cfg); /* json to string */ char *json_string = cJSON_Print(led_json); if(NULL != json_string) { /* Write json string to EEPROM */ at24cxxx_eeprom_write(0,(uint8_t *)json_string,strlen(json_string) + 1); free(json_string); /* Delete struct to json object */ if(led_json) s2j_delete_json_obj(led_json); } } if(strcmp(argv[1],"decode") == 0) { } return 0; }
执行上述测试代码后,dump EEPROM 的数据,发现0地址已经按照json 的数据格式写入测试数据了。
上述验证说明struct 转化成json 的方向已经符合预期了,我们继续验证Cjson 对象转化成结构体成员。
我们继续添加如下代码验证从cJSON 转换成结构体成员的功能,添加如下测试代码
void * cfg_json_to_struct(cJSON * pjson) { /* Create struct object */ s2j_create_struct_obj(struct_cfg,cfg_t); /* Get struct from pjson */ s2j_struct_get_basic_element(struct_cfg,pjson,string,cfg_name); s2j_struct_get_basic_element(struct_cfg,pjson,int,status); return struct_cfg; } unsigned int s2j(char argc,char *argv[]) { cJSON * led_json = NULL; static cfg_t led_cfg; led_cfg.cfg_name[0] = 'L'; led_cfg.cfg_name[1] = 'E'; led_cfg.cfg_name[2] = 'D'; led_cfg.cfg_name[3] = '\0'; led_cfg.status = 1; if(strcmp(argv[1],"decode") == 0) { led_json = cfg_struct_to_json(&led_cfg); cfg_t * led_cfg_cov = cfg_json_to_struct(led_json); if(memcmp(&led_cfg,led_cfg_cov,sizeof(cfg_t)) == 0) { LOG_I("S2J json to struct trans ok"); } else { LOG_E("S2J json to struct trans failed"); } if(led_cfg_cov) s2j_delete_struct_obj(led_cfg_cov); if(led_json) s2j_delete_json_obj(led_json); } return 0; }
验证结果如下已经正常输出OK的日志,至此我们一进简单的验证课struct2json库的基本功能