FStruct 正在参加
2021 年度 OSC 中国开源项目评选
,请投票支持!
FStruct 在
2021 年度 OSC 中国开源项目评选
中已获得 {{ projectVoteCount }} 票,请投票支持!
2021 年度 OSC 中国开源项目评选
正在火热进行中,快来投票支持你喜欢的开源项目!
2021 年度 OSC 中国开源项目评选 >>>
中场回顾
FStruct 是一个用于 C++ 序列化的开源库,采用非入侵方式,无需在原有结构体上进行修改,目前支持基础类型,结构体,以及vector,list,deque,set,map等复杂数据类型的序列化,支持JSON和XML两种数据格式,支持别名,支持忽略字段,等其他特性,最少两行代码即可完成转换。
使用git命令将代码拉取到本地:git clone
https://github.com/HuaGouFdog/FdogSerialize.git
linux编译:g++ -std=c++11 ../FStruct.cpp main.cpp -o main -w
代码中有使用到C++11特性,使用到了正则表达式,若是linux编译,需保证gcc版本在4.9(4.8不支持正则表达式)。
欢迎体验,如果对您有帮助,不妨给我一个
⭐️
,同时本人能力有限,若您有更好的解决方案,欢迎给我留言。
😊
😊
😊
使用过java或者go的人知道这些语言在进行序列化和反序列化是很容易的,对于C++而言,这是困难的,根本原因是C++不支持反射,虽然C++不支持反射,但是我们依旧可以通过自己的方式来保存对象元信息来实现序列化与反序列化,记得我在大二时用C++写的一个client-server小项目,自己规定了传输的数据格式(当时觉得自己解析Json很麻烦),第一个字段应该是什么,第二个字段应该是什么,正是因为没有方便的函数进行转换,我每次都需要使用非常繁琐的代码去拼出一个可以传递的字符串,是的,这样确实可以完成我想要的功能,但是我自己定的数据格式只适合自己用,这种方式长期必然行不通,而大多数人使用JSON和XML这两种数据格式来保存数据,如果我的项目想要使用这种大众化的数据格式,我又将重构我的代码。
我试着在github寻找一些用于C++的序列化与反序列的库,看看有没有什么办法可以帮助我快速把对象转变成JSON,我找到了一些类似的库,但是获得或多或少存在一些问题。
👉不太和我心意的设计:
使用者需要添加过多代码❌
采用入侵方式,需要改变原有的结构体❌
不需要入侵,但是在注册的时候需要一个一个指定类型❌
只支持基础类型组成的结构体转换❌
不支持别名(由于go的特性,在go中经常被使用)❌
不支持忽略字段❌
不支持指针类型(如果原项目中存在指针类型便需要指针类型)❌
长痛不如短痛, 自己动手写一个吧。(一开始想的简单了,说实话后面还是有些难度的,但是没关系,一项一项攻破。)
👉第一阶段分为下面几个部分:
支持由基础类型和Json互转✔️
支持由基础类型组成的数组和json互转✔️
支持由基础类型组合成结构体类型和Json互转✔️
支持由结构体包含结构体的类型和Json互转✔️
支持vector类型和json互转✔️
支持list类型和json互转✔️
支持map类型和json互转✔️
支持set类型和json互转✔️
支持deque类型和json相转✔️
👉第二阶段分为下面几个部分:
结构体多层嵌套(如果成员包括STL容器,则STL容器支持基本类型)✔️
对第一阶段所使用的接口进行优化,将六个接口整合为两个:FJson/FObject,方面调用✔️
👉第三阶段分为下面几个部分:
支持对json字符串进行格式正确判断🕒
支持获取某个字段是否存在🕒
支持获取某个字段的值,而无须先进行序列化🕒
结构体多层嵌套(如果成员包括STL容器,则STL容器支持基本类型)🕒
👉第四阶段分为下面几个部分:
支持必选字段和可选字段,当必选字段无值时,进行报错(定义为指针类型即为可选字段)🕒
支持XML数据格式的转换🕒
👉杂项支持:
支持别名✔️
支持字段忽略✔️
支持忽略大小写✔️
支持字段为空,则不进行序列化🕒
支持模糊转换🕒
暂时就想到怎么多,打钩的是已经实现的,如果您有更好或者更有趣的建议,麻烦告诉我!
🎄类型支持
虽然school这个结构体包含了一种最基础类型和一种自定义类型,但追寻本质,自定义类型的底层都属于
最基本类型
。
因此school这个结构体完全可以被正常解析,事实上是任意类型都可以解析。
🎄接口支持
FStructm目前期望提供的接口支持:
char
ch =
'
A
'
;
//
ASCII码十进制为98
//
如果一个包含char的结构体转Json,检测到ch的类型为char将自动转为字符,//注意C++的中的转义
std::string json =
"
{
\"
ch
\"
:98}
"
;
//
相对的,如果一个包含char的json想转为struct
std::string json =
"
{
\"
ch
\"
:98}
"
;
//
又或者你不知道字符'A'的ASCII码是多少,那么可以使用如下方式,一般情况下不会遇到自己写json
std::string json =
"
{
\"
ch
\"
:
\"
char('A')
\"
}
"
;
//
库会根据ch的类型,若ch为char类型自动将\"char('A')\"转为98
👉目前支持20个成员的结构体,也可自行添加。
//
添加方法:在FStruct.h底部,找到
#
define
REGISTEREDMEMBER_s_20
(TYPE, PLACE, metaInfoObjectList, size, arg1, ...) \
REGISTEREDMEMBER_s
(TYPE, metaInfoObjectList, arg1);
//
当前支持20,若您有更大的需求,可以根据已有格式自行添加,当然如果您觉得20个太多,也可以自行删除。
👉关于指针类型的支持
对于指针类型的支持,内部在处理指针时,将判断指针是否为nullpr,如果为nullpr则不参与序列化,如果不为nullpr则参与序列化,指针类型在这里有可选字段的属性,您可赋值,也可不赋值,当遇到非必传字段时,建议您使用指针类型。
👉vector的问题
vector的问题不是一个STL容器,出于
空间优化的原因
,C++ 标准(最早可追溯到 C++98)明确地将 vector 称为特殊的标准容器,其中每个 bool 仅使用一位空间而不是像普通 bool 那样使用一个字节( 实现一种“动态位集”)。
标准库提供了两个替代品:deque,bitset
👉文件说明
该库包括defintion.h,FStruct.h,FStruct.cpp,三个文件。
FStruct.h,FStruct.cpp提供的所有可用接口,已在<接口支持>中列出,您可按需调用。
defintion.h头文件用于宏替换某些必要的代码,如果一个参与序列化与反序列化的结构体中存在某个成员也是结构体,那么您应该在defintion.h对应的宏里面添 加相应的定义。
example.md提供了足够详细的测试示例(如果您觉得还有缺陷,可与我联系)。
对应的example.cpp提供了example.md所提供示例的代码。