FStruct

C++ 序列化
授权协议 Apache
开发语言 C/C++
所属分类 开发工具、 C/C++开发工具
软件类型 开源软件
地区 国产
投 递 者 颜德馨
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

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,我找到了一些类似的库,但是获得或多或少存在一些问题。

��不太和我心意的设计:

  1. 使用者需要添加过多代码❌
  2. 采用入侵方式,需要改变原有的结构体❌
  3. 不需要入侵,但是在注册的时候需要一个一个指定类型❌
  4. 只支持基础类型组成的结构体转换❌
  5. 不支持别名(由于go的特性,在go中经常被使用)❌
  6. 不支持忽略字段❌
  7. 不支持指针类型(如果原项目中存在指针类型便需要指针类型)❌

长痛不如短痛, 自己动手写一个吧。(一开始想的简单了,说实话后面还是有些难度的,但是没关系,一项一项攻破。)

��第一阶段分为下面几个部分:

  1. 支持由基础类型和Json互转✔️
  2. 支持由基础类型组成的数组和json互转✔️
  3. 支持由基础类型组合成结构体类型和Json互转✔️
  4. 支持由结构体包含结构体的类型和Json互转✔️
  5. 支持vector类型和json互转✔️
  6. 支持list类型和json互转✔️
  7. 支持map类型和json互转✔️
  8. 支持set类型和json互转✔️
  9. 支持deque类型和json相转✔️

��第二阶段分为下面几个部分:

  1. 结构体多层嵌套(如果成员包括STL容器,则STL容器支持基本类型)✔️
  2. 对第一阶段所使用的接口进行优化,将六个接口整合为两个:FJson/FObject,方面调用✔️

��第三阶段分为下面几个部分:

  1. 支持对json字符串进行格式正确判断��
  2. 支持获取某个字段是否存在��
  3. 支持获取某个字段的值,而无须先进行序列化��
  4. 结构体多层嵌套(如果成员包括STL容器,则STL容器支持基本类型)��

��第四阶段分为下面几个部分:

  1. 支持必选字段和可选字段,当必选字段无值时,进行报错(定义为指针类型即为可选字段)��
  2. 支持XML数据格式的转换��

��杂项支持:

  1. 支持别名✔️
  2. 支持字段忽略✔️
  3. 支持忽略大小写✔️
  4. 支持字段为空,则不进行序列化��
  5. 支持模糊转换��

暂时就想到怎么多,打钩的是已经实现的,如果您有更好或者更有趣的建议,麻烦告诉我!


��类型支持

序号 基础类型 说明 序号 基础类型 说明
1 bool 布尔类型 9 unsigned int 无符号整型
2 char 无符号字符型 10 long 长整型
3 unsigned char 无符号字符型 11 unsigned long 无符号长整型
4 **char *** 字符指针(字符串类型) 12 long long 超长整型
5 short 短整型 13 unsigned long long 无符号超长整型
6 unsigned short 无符号短整型 14 float 单精度浮点类型
7 int 整型 15 double 双进度浮点类型
8 string 字符串类型 16 long double 长双进度浮点类型

基于C++的基础类型,FStruct支持如上的十六种类型,只要你的结构体中最基本类型在这十六种范围之内,便可完成转换。

��最基本类型说明:

struct headmaster{
	char * name;
	int age;
};

struct school{
	char * schoolName;
	headmaster info;
};

虽然school这个结构体包含了一种最基础类型和一种自定义类型,但追寻本质,自定义类型的底层都属于最基本类型

因此school这个结构体完全可以被正常解析,事实上是任意类型都可以解析。


��接口支持

FStructm目前期望提供的接口支持:

已完成:

接口支持 说明
FJson(string & json_, T & object_) object转json
FObject( T & object_, string & json_, string name = "") json转object
setAliasName(string Type, string memberName, string AliasName) 使用别名(单个变量设置)
setIgnoreField(string Type, string memberName) 忽略字段(单个变量设置)
setIgnoreLU(string Type, string memberName) 忽略大小写(单个变量设置)

未完成:

接口支持 说明
FXml() object转xml
FObjectX() xml转object
setAliasNameAll() 使用别名(支持多个同时设置)
setIgnoreFieldAll() 忽略字段(支持多个同时设置)
setIgnoreLUAll() 忽略大小写(支持多个同时设置)
setFuzzy(string Type)() 模糊转换(设置后,对于字段名设置不正确,将尝试模糊匹配,考虑加入到默认)
JsonValid() json格式是否正确
XmlValid() xml格式是否正确
Exist() 查找字段是否存在
GetIntValue 获取int类型的值
GetDoubleValue 获取double类型的值
GetStringValue 获取string类型的值
GetBoolValue 获取bool类型的值
   

如果您还希望提供什么好的接口,请联系我。

��测试文档(即使用说明)

example.md

��可能的疑问


  1. ��为什么char * 类型算作基础类型

​ 因为json中除了数值型数据,剩下的便是字符串类型,考虑到字符串使用的频率,再加上C++对于C兼容的原因,决定把char *作为最基础类型,除了char * 可以存储字符串,也可使用string存储字符串。

  1. ��char 类型怎么传递

    由于JSON并不支持单引号,所以将使用数值传递并还原,例如:

    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
  2. ��目前支持20个成员的结构体,也可自行添加。

    //添加方法:在FStruct.h底部,找到
    #define REGISTEREDMEMBER_s_20(TYPE, PLACE, metaInfoObjectList, size, arg1, ...) \
    REGISTEREDMEMBER_s(TYPE, metaInfoObjectList, arg1);
    
    //当前支持20,若您有更大的需求,可以根据已有格式自行添加,当然如果您觉得20个太多,也可以自行删除。
  3. ��关于指针类型的支持

​ 对于指针类型的支持,内部在处理指针时,将判断指针是否为nullpr,如果为nullpr则不参与序列化,如果不为nullpr则参与序列化,指针类型在这里有可选字段的属性,您可赋值,也可不赋值,当遇到非必传字段时,建议您使用指针类型。

  1. ��vector的问题

​ vector的问题不是一个STL容器,出于空间优化的原因,C++ 标准(最早可追溯到 C++98)明确地将 vector 称为特殊的标准容器,其中每个 bool 仅使用一位空间而不是像普通 bool 那样使用一个字节( 实现一种“动态位集”)。

​ 标准库提供了两个替代品:deque,bitset

  1. ��文件说明

​ 该库包括defintion.h,FStruct.h,FStruct.cpp,三个文件。

​ FStruct.h,FStruct.cpp提供的所有可用接口,已在<接口支持>中列出,您可按需调用。

​ defintion.h头文件用于宏替换某些必要的代码,如果一个参与序列化与反序列化的结构体中存在某个成员也是结构体,那么您应该在defintion.h对应的宏里面添 加相应的定义。

​ example.md提供了足够详细的测试示例(如果您觉得还有缺陷,可与我联系)。

​ 对应的example.cpp提供了example.md所提供示例的代码。

 


��许可

该项目签署了Apache-2.0 License,详情请参见LICENSE

根据 Apache 许可,版本 2.0(“许可”)获得许可 除非遵守许可,否则您不得使用此文件。


��其他

如果FStruct对您有帮助的话,请给FStruct点个star!

如果觉得FStruct好用的话,可以推广给你的朋友们!

如果您有更好的建议,欢迎您告诉我!

  • FStruct是一个用于C++对象(结构体,STL容器等)和json/xml字符串之间进行转换的库。 采用非入侵方式,无需在原有结构体上进行修改,目前支持基础类型,结构体,以及vector,list,deque,set,map等复杂数据类型的序列化,支持JSON和XML两种数据格式,支持别名,支持忽略字段,等其他特性,最少两行代码即可完成转换。 使用过java或者go的人知道这些语言在进行序列化和

  • 引擎版本为4.24 在UE4C++中,我们能常常需要创建FStruct来满足我们的数据需求。 但在前面的开发当中,我发现网上存在的教程往往都是蓝图创建FStruct,或者在家在类中创建FStruct,又或者关于C++中创建单独的FStruct,却没有完整代码的。 因此我记录一下如何创建一个单独的FStruct文件。 第一步: 直接在Vs中,右键新建一个.h文件。 第二步: 仿照下面的代码进行输入,

 相关资料
  • 我正在尝试使用kryo序列化和反序列化到二进制。我想我已经完成了序列化,但似乎无法反序列化。下面是我正在处理的代码,但最终我想存储一个字节[],然后再次读取它。文档只显示了如何使用文件。

  • 问题内容: 我尝试过在Java和Android之间实现跨平台序列化。我使用了Serializable,并将我的代码在Android中与台式机Java放在同一软件包中。 来源:java-desktop序列化 资料来源:Android-反序列化 学生是一类,实现了Serializable。在桌面上,我将学生实例序列化为“ thestudent.dat”。我将此文件放在Android设备上的SD卡上,并

  • 问题内容: 我注意到存储在Redis中的某些序列化对象在反序列化方面遇到问题。 当我对Redis中存储的对象类进行更改时,通常会发生这种情况。 我想了解问题,以便为解决方案设计一个清晰的方案。 我的问题是,什么导致反序列化问题?移除公共/私人财产会引起问题吗?也许添加新属性?向类添加新功能会产生问题吗?那么更多的构造函数呢? 在我的序列化对象中,我有一个属性Map,如果我更改(更新了一些属性,添加

  • 问题内容: Golang中将结构序列化和反序列化为字符串的最佳方法(完整性和性能)是什么,反之亦然? 例如,如果我有这个结构: 我想将其存储在Redis上并取回。我试过保存,整型和字符串,这很好,但是如何存储结构对象? 问题答案: 使用gob和base64可以解决问题,例如: 当您需要序列化自定义结构或类型(例如struct)时,只需添加以下行:

  • 主要内容:1 Java序列化和反序列化,2 Java序列化的优点,3 java.io.Serializable接口,4 Java ObjectOutputStream,5 Java ObjectInputStream,6 Java序列化的例子,7 Java反序列化的例子1 Java序列化和反序列化 Java中的序列化是一种将对象状态写入字节流的机制。它主要用于Hibernate,RMI,JPA,EJB和JMS技术。 序列化的反向操作称为反序列化,其中字节流被转换为对象。序列化和反序列化过程与平台

  • FAQs in section [36]: [36.1]“序列化”是什么东东? [36.2] 如何选择最好的序列化技术? [36.3] 如何决定是要序列化为可读的(“文本”)还是不可读的(“二进制”)格式? or non-human-readable ("binary") format?") [36.4] 如何序列化/反序列化数字,字符,字符串等简单类型? [36.5] 如何读/写简单类型为可读的

  • 上一小节我们学习了 Java 的输入输出流,有了这些前置知识点,我们就可以学习 Java 的序列化了。本小节将介绍什么是序列化、什么是反序列化、序列化有什么作用,Serializable 接口以及 Externalizable 接口,常用序列化工具介绍等内容。 1. 序列化与反序列化 序列化在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式,以留待后续在相同或另一台计算机环境中,能

  • 通常情况下,这种形式是基于文本的,它被用来发送Django的数据,当然,序列化处理的形式也有例外(基于文本或者相反)。 参见 如果您只是想从表中获取一些数据到序列化形式,可以使用dumpdata管理命令。 序列化数据 从最高层面来看,序列化数据是一项非常简单的操作 from django.core import serializers data = serializers.serialize("x