当前位置:首页 > 科技  > 软件

C语言中一种cJSON与结构体互转的方法

来源: 责编: 时间:2024-02-29 14:43:31 305观看
导读前言json是目前最为流行的文本数据传输格式,特别是在网络通信上广泛应用,随着物联网的兴起,在嵌入式设备上,也需要开始使用json进行数据传输,那么,如何快速简洁地用C语言进行json的序列化和反序列化呢?当前,应用最广泛的C语言

前言

json是目前最为流行的文本数据传输格式,特别是在网络通信上广泛应用,随着物联网的兴起,在嵌入式设备上,也需要开始使用json进行数据传输,那么,如何快速简洁地用C语言进行json的序列化和反序列化呢?oEy28资讯网——每日最新资讯28at.com

当前,应用最广泛的C语言json解析库当属cJSON,但是,使用cJSON读json进行序列化和反序列化,需要根据key一个一个进行处理,会导致代码冗余,逻辑性不强,哪有没有更好的方法呢?oEy28资讯网——每日最新资讯28at.com

oEy28资讯网——每日最新资讯28at.com

思路

在Android平台,一般会使用gson等工具解析json,这些工具将json直接映射成对象,在C语言上使用对象的概念,我们需要借助结构体,然而,最大的问题在于,C语言没有高级语言具有的反射机制,直接从json映射到结构体对象几乎是不可能的。oEy28资讯网——每日最新资讯28at.com

怎么解决呢,既然C语言没有反射机制,那么我们可以自己定义一套类似于反射的机制,这里我将其称之为结构体数据模型,在数据模型中,我们需要准确地描述结构体的特征,包括结构体各成员的名称,类型,在结构体中的偏移。oEy28资讯网——每日最新资讯28at.com

有了这些,我们可以在解析josn的时候,将解析得到的数据直接写入到对应的内存里面去,或者是在序列化的时候,直接从对应的内存中读取数据,进行处理。oEy28资讯网——每日最新资讯28at.com

实现

CSON正是采用上面说到的思路,使用数据模型对结构体进行描述,然后基于cJSON,根据数据模型进行解析,将解析得到的数据直接写入到对应的内存区域,从而实现从json到结构体对象的映射。oEy28资讯网——每日最新资讯28at.com

CSON最基本的数据模型定义如下:oEy28资讯网——每日最新资讯28at.com

typedef struct cson_model{    CsonType type;                      /**< 数据类型 */    char *key;                          /**< 元素键值 */    short offset;                       /**< 元素偏移 */} CsonModel;

通过type描述结构体成员的数据类型,key描述该成员在json中对应的字段,offset描述该结构体成员在结构体中的偏移,CSON在解析json的时候,根据type调用相应的cJSON API并传递key作为参数,得到解析出的数据,然后根据offset将数据写入到对应的内存空间。oEy28资讯网——每日最新资讯28at.com

比如说这样一个结构体:oEy28资讯网——每日最新资讯28at.com

struct project{    int id;    char *name;}

该结构体包含两个成员,对于成员id,我们使用数据模型对其进行描述:oEy28资讯网——每日最新资讯28at.com

{.type=CSON_TYPE_CHAR, key="id", offset=0}

对于结构体的每个成员,都进行数据模型的定义,就可以得到一个完整的结构体数据模型,CSON会根据这个模型,进行解析。oEy28资讯网——每日最新资讯28at.com

因为是通过直接写内存的方式,所以在写不同类型的量到内存中时,会多次用到强制转型,导致CSON中赋值的代码都类似于:oEy28资讯网——每日最新资讯28at.com

*(int *)((int)obj + model[i].offset) = (int)csonDecodeNumber(json, model[i].key);

当然,上面说到的数据模型,只适用于基本数据类型的数据,对于子结构体,链表,数组等,需要对数据模型的定义进行扩充,有兴趣的朋友可以直接阅读CSON源码。oEy28资讯网——每日最新资讯28at.com

CSON使用实例

(1) 声明结构体:oEy28资讯网——每日最新资讯28at.com

/** 项目结构体 */struct project{    int id;    char *name;};/** 仓库结构体 */struct hub{    int id;    char *user;    struct project *cson;};

(2) 定义数据模型:oEy28资讯网——每日最新资讯28at.com

对每一个需要使用cson的结构体,都需要定义相对应的数据模型oEy28资讯网——每日最新资讯28at.com

/** 项目结构体数据模型 */CsonModel projectModel[] ={    CSON_MODEL_OBJ(struct project),    CSON_MODEL_INT(struct project, id),    CSON_MODEL_STRING(struct project, name),};/** 仓库结构体数据模型 */CsonModel hubModel[] ={    CSON_MODEL_OBJ(struct hub),    CSON_MODEL_INT(struct hub, id),    CSON_MODEL_STRING(struct hub, user),    CSON_MODEL_STRUCT(struct hub, cson, projectModel, sizeof(projectModel)/sizeof(CsonModel))};

(3) 使用CSON解析:oEy28资讯网——每日最新资讯28at.com

只需要定义好数据模型,就可以使用CSON读json进行序列化和反序列化oEy28资讯网——每日最新资讯28at.com

void csonDemo(void){    char *jsonDemo = "{/"id/": 1, /"user/": /"Letter/", /"cson/": {/"id/": 2, /"name/": /"cson/"}}";    /** 解析json */    struct hub *pHub = csonDecode(jsonDemo, hubModel, sizeof(hubModel)/sizeof(CsonModel));    printf("hub: id: %d, user: %s, project id: %d, project name: %s/r/n",        pHub->id, pHub->user, pHub->cson->id, pHub->cson->name);    /** 序列化对象 */    char *formatJson = csonEncodeFormatted(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));    printf("format json: %s/r/n", formatJson);    /** 释放结构体对象 */    csonFree(pHub, hubModel, sizeof(hubModel)/sizeof(CsonModel));    /** 释放序列化生成的json字符串 */    csonFreeJson(formatJson);}

运行结果:oEy28资讯网——每日最新资讯28at.com

hub: id: 1, user: Letter, project id: 2, project name: csonformat json: {        "id":   1,        "user": "Letter",        "cson": {                "id":   2,                "name": "cson"        }}

可以看到,无论是解析json,还是序列化结构体到json,在使用CSON的情况下,都只需要一行代码就可以解决,同样的操作,在使用原生cJSON的情况下,你可能需要多次判断,解析元素。oEy28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-75352-0.htmlC语言中一种cJSON与结构体互转的方法

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 掌握Python匿名大师:lambda函数使用技巧大公开

下一篇: 字节跳动最热门的15个前端开源项目

标签:
  • 热门焦点
  • 天猫精灵Sound Pro体验:智能音箱没有音质?来听听我的

    这几年除了手机作为智能生活终端最主要的核心之外,第二个可以成为中心点的产品是什么?——是智能音箱。 手机在执行命令的时候有两种操作方式,手和智能语音助手,而智能音箱只
  • Golang 中的 io 包详解:组合接口

    io.ReadWriter// ReadWriter is the interface that groups the basic Read and Write methods.type ReadWriter interface { Reader Writer}是对Reader和Writer接口的组合,
  • 微信语音大揭秘:为什么禁止转发?

    大家好,我是你们的小米。今天,我要和大家聊一个有趣的话题:为什么微信语音不可以转发?这是一个我们经常在日常使用中遇到的问题,也是一个让很多人好奇的问题。让我们一起来揭开这
  • 消费结构调整丨巨头低价博弈,拼多多还卷得动吗?

    来源:征探财经作者:陈香羽随着流量红利的退潮,电商的存量博弈越来越明显。曾经主攻中高端与品质的淘宝天猫、京东重拾&ldquo;低价&rdquo;口号。而过去与他们错位竞争的拼多多,靠
  • 东方甄选单飞:有些鸟注定是关不住的

    作者:彭宽鸿来源:华尔街科技眼&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;东方甄选创始人俞敏洪带队的&ldquo;7天甘肃行&rdquo;直播活动已在近日顺利收官。成立后一
  • Android 14发布:首批适配机型公布

    5月11日消息,谷歌在今天凌晨举行了I/O大会,本次发布会谷歌带来了自家的AI语言模型PaLM 2、谷歌Pixel Fold折叠屏、谷歌Pixel 7a手机,同时发布了Androi
  • iQOO Neo8系列或定档5月23日:首发天玑9200+ 安卓跑分王者

    去年10月,iQOO推出了iQOO Neo7系列机型,不仅搭载了天玑9000+,而且是同价位唯一一款天玑9000+直屏旗舰,一经上市便受到了用户的广泛关注。在时隔半年后,
  • “买真退假” 这种“羊毛”不能薅

    □ 法治日报 记者 王春   □ 本报通讯员 胡佳丽  2020年初,还在上大学的小东加入了一个大学生兼职QQ群。群主&ldquo;七王&rdquo;在群里介绍一些刷单赚
  • 北京:科技教育体验基地开始登记

      北京“科技馆之城”科技教育体验基地登记和认证工作日前启动。首批北京科技教育体验基地拟于2023年全国科普日期间挂牌,后续还将开展常态化登记。  北京科技教育体验基
Top