0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何用C语言进行json的序列化和反序列化

麦辣鸡腿堡 来源:CSDN博客 作者:NevermindZZT 2023-10-07 11:05 次阅读

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

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

思路

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

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

有了这些,我们可以在解析josn的时候,将解析得到的数据直接写入到对应的内存里面去,或者是在序列化的时候,直接从对应的内存中读取数据,进行处理。

实现

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

CSON最基本的数据模型定义如下:

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

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

比如说这样一个结构体:

struct project
{
    int id;
    char *name;
}

该结构体包含两个成员,对于成员id,我们使用数据模型对其进行描述

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

对于结构体的每个成员,都进行数据模型的定义,就可以得到一个完整的结构体数据模型,CSON会根据这个模型,进行解析。

因为是通过直接写内存的方式,所以在写不同类型的量到内存中时,会多次用到强制转型,导致CSON中赋值的代码都类似于:

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

当然,上面说到的数据模型,只适用于基本数据类型的数据,对于子结构体,链表,数组等,需要对数据模型的定义进行扩充,有兴趣的朋友可以直接阅读CSON源码。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    6837

    浏览量

    88754
  • C语言
    +关注

    关注

    180

    文章

    7595

    浏览量

    135923
  • 模型
    +关注

    关注

    1

    文章

    3121

    浏览量

    48663
  • JSON
    +关注

    关注

    0

    文章

    117

    浏览量

    6929
收藏 人收藏

    评论

    相关推荐

    如何使用Serde进行序列化反序列化

    Serde 是一个用于序列化反序列化 Rust 数据结构的库。它支持 JSON、BSON、YAML 等多种格式,并且可以自定义序列化反序列化
    的头像 发表于 09-30 17:09 1237次阅读

    怎么支持PIC32中的JSON解析和序列化

    我正在寻找支持或库,允许我将JSON对象序列化为char数组,并将char数组/字符串解析为JSON对象。我查看了JSMN库,但它看起来只是解析,而不是序列化。我目前在ARDUINO板
    发表于 11-28 16:46

    Java序列化的机制和原理

    对象的序列化反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍。Java序列化算法透析Serializati
    发表于 07-10 07:27

    Virtex ISERDES_NODELAY对快速4线总线进行反序列化怎么实现?

    你好朋友。我想使用Virtex ISERDES_NODELAY对快速4线总线进行反序列化。总线大约为700 MHz。我想确保反序列化的信号不是异相的。我的意思是,如果其中一个ISERDES由于内部路由延迟而稍后将复位,则
    发表于 06-01 16:54

    c语言序列化反序列化有何区别

    这里写自定义目录标题c语言序列化反序列化tplut.htplut.c测试代码参考c
    发表于 07-14 07:32

    关于c语言序列化反序列化的知识点看完你就懂了

    关于c语言序列反序列化的知识点你就懂了
    发表于 10-15 08:47

    SpringMVC JSON框架的自定义序列化反序列化

    自定义序列化改造,但没有提供反序列化过滤器,来实现对应的功能。方案:@JSONField注解回到对JSON报文String类型的值执行trim操作,官网支持@JSONField注解的属性设置(要求
    发表于 10-10 16:02

    理解PHP反序列化漏洞

    理解PHP反序列化漏洞
    发表于 09-07 11:03 7次下载
    理解PHP<b class='flag-5'>反序列化</b>漏洞

    java序列化反序列化范例和JDK类库中的序列化API

    一、序列化反序列化的概念 把对象转换为字节序列的过程称为对象的序列化。 把字节序列恢复为对象的过程称为对象的
    发表于 09-27 10:13 6次下载

    static属性为什么不会被序列化

    实现序列化反序列化为什么要实现Serializable接口?
    的头像 发表于 07-15 11:03 1724次阅读

    C#实现对象序列化的三种方式是什么

    很多小伙伴一提到序列化,都会想到二进制序列化,但其实序列化并不仅仅只是二进制序列化,我们常说的对象序列化有三种方式,分别是二进制
    的头像 发表于 02-22 16:11 1129次阅读
    <b class='flag-5'>C</b>#实现对象<b class='flag-5'>序列化</b>的三种方式是什么

    什么是序列化 为什么要序列化

    什么是序列化? “序列化”(Serialization )的意思是将一个对象转化为字节流。 这里说的对象可以理解为“面向对象”里的那个对象,具体的就是存储在内存中的对象数据。 与之相反的过程是“反序列化
    的头像 发表于 09-14 17:22 2423次阅读
    什么是<b class='flag-5'>序列化</b> 为什么要<b class='flag-5'>序列化</b>

    ROS中的序列化实现

    理解了序列化,再回到ROS。我们发现,ROS没有采用第三方的序列化工具,而是选择自己实现,代码在roscpp_core项目下的roscpp_serialization中,见下图。这个功能涉及的代码量
    的头像 发表于 09-14 17:26 872次阅读

    Spring Boot时配置JSON序列化选项的几种方法

    在Spring Boot Web 项目中,当使用JSON格式接收数据和返回数据的时候,Spring Boot 默认使用一个ObjectMapper实例来序列化响应和反序列化请求。 在本文中,我们将
    的头像 发表于 10-09 10:26 2035次阅读

    Java序列化怎么使用

    转换方式就叫做序列化。将文件或者网络传输中得到的 byte[] 数组转换为 java 对象就叫做反序列化。 怎么使用 如果一个 Java 对象要能被序列化,必须实现一个特殊
    的头像 发表于 10-10 14:19 414次阅读