![](https://s5-media.51cto.com/ost/pc/static/noavatar.gif)
冷兵器与热兵器的PK | iSula与JSON的斗争
对于各种习惯高级语言的伙伴们来说,JSON的解析和生成是如呼吸般简单自然的事情。但是对于C语言,JSON的解析和生成就麻烦了。根本原因是由于C语言不支持反射,没办法对JSON做动态解析和生成。但是,容器引擎中涉及大量的JSON解析和生成。
那么,我们为了更好的和JSON进行和谐相处,做了哪些努力呢?
大体上,iSula经历了几个阶段,为了更好的感受这几个阶段的差距:我觉得通过武器的不同时代来感受一下。
# 冷兵器时代
C语言还是有一些JSON解析的库的,例如yaj1,cjson等等;这些库提供了把JSON字符串解析为tree结构的元素集合,然后通过遍历书可以快速的找到JSON的key/value的对应关系和值。
而且也能自己构建对应的元素结合tree,然后生成JSON字符串。那么,如何通过这些库来做JSON和C结构体直接的相互转换呢?
以yaj1为例,实现一个isula_version结构体的marsha和unmarshal.
这种方式虽然没法和支持动态解析的语言一样高效简单,但是也算完成了任务。如果动态解析是热兵器,这个勉强能算是长矛了。
从示例来看,完成一个结构体和JSON的映射大概需要160行左右的代码。而上面只是一个简单的结构体,而且有的项目有很多这种结构体需要做映射。这种原始的方式在大型项目中很难保证参与人员代码质量可控;而且效率低下。
主要的缺陷总结如下:
• 映射工作量较大;
• 对每种结构体需要单独适配代码,无法实现自动化;
• 效率低下;
• 代码质量不可控;
# 伪热兵器时代
由于C不支持反射,没法做到动态解析。但是可以通过其他途径简化解析流程、提高效率、实现自动化以及实现代码可控。为了避免重复造论子,17年的时候发现了libocisper项目,提供了一个解决C语言JSON映射的思路:
• 通过json schema描述JSON字符串的结构信息;
• 通过python解析json schema信息;
• 根据json schema信息自动生成C结构体和JSON的映射代码;
这种方式,可以解决上面的上一章节的几个缺陷:
• 工作量大大减少,这需要写好json schema文件即可;
• 自动化解析代码工作;
• 效率很高;
• 代码质量可控,取决于生产框架的质量;
注:libocispes早期只能用于解析oci spec的json,在我们发现之后,多个开发人员参与社区,提供了大量的功能升级,才有了今天的强大能力。
iSula集成libocispec结构
iSula当前把JSON映射相关的代码,统一放到lcr项目中进行管理,通过一个动态库和头文件提供相应功能。
生成代码的开源python框架结构如下:
json schema文件存放结构(由于iSula涉及的所有JSON结构都在该目录下,所以存在大量的schema文件)如下:
然后在cmake的时候,会触发python框架,根据schema目录下面所有的schema来生成对应的映射代码。会看到如下提示信息。
那么,现在我们如果需要对一个新的结构体和JSON进行映射,需要做的事情就是在json schema目录下面新增一个对应的schema文件即可。这里以上一章节的isula_version为例。
新增schema文件isula_version.json:
重新cmake,可以看到新生成了两个文件:
生成的代码对外的接口如下:
测试用例:
执行结果如下:
通过libocispec可以实现接近于高级语言的marshal和 unmarshal 了,只需要简单编写schema文件即可,极大的提高了效率,并且依托开源社区可以提高代码质量。但是,还是存在一些缺陷。
例如golang中,marshal之后的结构体可以通过map[string]interface保存,可以完整的记录JSON字 符串中的信息。而我们当前的实现,只能根据schema来解析JSON字符串,因此,存在信息丢失的情况。有些场景,规范只规定了主体的JSON结构,并且支持拓展配置,例如CNI规范。
# 近乎热兵器时代
为了解决信息丢失的问题,我们通过在结构体中记录原始的元素集合tree的方案,unmarshal的时候不 会丢失原始信息,marshal的时候解析记录的元素信息,从而实现原始数据完整的传递。
具体解决方案见官方PR:https://github.com/containers/libocispec/pull/56
使用方式和上面的基本一致,差异主要包括以下几部分:
1. 生成的代码有部分差异(_residual);
2. 解析是需要指定 struct parser_context 参数为 OPT_PARSE_FULLKEY ;
3. 效果如下
可以看到拓展的信息,完整的传递下去了。通过这种方式完美的解决了CNI的拓展配置的支持,从而解 决了iSulad动态支持多种插件的技术瓶颈。
上面的方案已经基本和支持反射的语言实现的功能相近了,但是,还是存在部分缺陷的。例如,动态修改JSON结构的数据会比较麻烦,需要对底层的解析库比较了解,而且比较麻烦。
虽然当前的框架还有一些缺陷,但是,我们的目标并不是实现一个完美的JSON和C结构体的映射框架, 而是解决容器引擎使用JSON的问题。而上面的方案,已经完全满足iSula当前的需求。
因此,目前没有进一步优化的需求。如果后续使用场景或者其他用户有需求,可以到libocispec的社区进行进一步的优化。
• https://github.com/containers/libocispec
• http://json-schema.org/
• https://github.com/lloyd/yajl/tree/master/example
• libocispec 社区:https://github.com/containers/libocispec
文章转载自公众号:openEuler
![](https://s5-media.51cto.com/ost/pc/static/noavatar.gif)
-
刚刚 与 华为“离婚” 的 荣耀,能否登上鸿蒙OS 的 大船?kekenai • 9975浏览 • 0回复
-
#2020征文-手机#浅谈JS 与 Java在手机APP中 的 混合开发方式执剑天涯奈我何 • 2.1w浏览 • 17回复
-
浅析鸿蒙中 的 Gn 与 Ninja(一)唐佐林 • 3.4w浏览 • 8回复
-
Android webview 与 js 交换 JSON 对象数据hackernew • 1.0w浏览 • 0回复
-
【今晚8点直播公开课】鸿蒙开发之JS 与 Java 的 混合使用 与 交互charjedu • 1.0w浏览 • 4回复
-
【答疑汇总】鸿蒙开发之JS 与 Java 的 混合使用 与 交互charjedu • 1.2w浏览 • 4回复
-
Hi3516 的 SAMGR--系统服务框架子系统-10-Client 与 Server 的 IPC来往liangkz_梁开祝 • 1.2w浏览 • 3回复
-
JS UI框架下FA 与 PA是如何交互 的开源基础软件社区官方 • 1.5w浏览 • 6回复
-
HarmonyOS 原子化服务 的 商业价值 与 构建思路开鸿吴丹 • 1.1w浏览 • 14回复
-
我 与 鸿蒙社区 的 一年是坚果呀 • 6230浏览 • 1回复
-
移植案例 与 原理 - HPM包描述文件bundle. jsonzhushangyuan_ • 1.1w浏览 • 4回复
-
HarmonyOS方舟开发框架容器类API 的 介绍 与 使用HarmonyOS开发者 • 5799浏览 • 0回复
-
HarmonyOS css样式 与 普通HTML css样式之间存在 的 区别中软小助手 • 7222浏览 • 2回复
-
HarmonyOSConnect套餐一:产品 json 文件配置 与 固件烧录拓维信息_hyh • 5143浏览 • 2回复
-
HarmonyOS - Java 与 Js 的 混合使用 与 交互中软小助手 • 7370浏览 • 1回复
-
App 与 Hap、Entry 与 feature,bundleName 与 packge,务必弄明白软通夏德旺 • 9023浏览 • 3回复
-
【FFH】OpenHarmony北向-Full SDK 的 获取 与 安装(使用系统接口)yoshioimai • 5594浏览 • 8回复
-
JSON 文档模型设计 的 常见误区及其 与 关系模型 的 区别laomugua • 1127浏览 • 0回复
-
JSON 文档模型设计 的 常见误区及其 与 关系模型 的 区别laomugua • 974浏览 • 0回复