C++ Class Mapped Google Protocol Buffer Message

2023-11-02

  1. 摘要
Google Protocol Buffer 是一个优秀的基于二进制的网络消息编解码框架。应用于项目时,可以节省不少的人力资源、开发时间和程序BUG。但其不足之处是protobuf编译器生成的C++消息类(或者Java等其他语言的消息类)冗余数据过多,需要依赖于protobuf的编解码库,一般情况下都不能用于作为业务逻辑对象。因此大部分情况下,程序都需要另外独立定义业务逻辑对象,并且使用protobuf定义相应(不一定100%相同)的消息,并手写代码,在protobuf消息对象和C++/Java业务对象之间进行转换。
protobuf消息还有另外一个缺点,是数据类型不够丰富,特别是指针,map集合不支持,你支持继承。通过required、optional属性的扩展可以让其支持指针,通过多字段,也可以让其支持map集合。
因在工程中,有太多的,太过于相似的转换代码,因此才有想法写一个C++类与google protobuf消息直接进行转换的工具。当然一次为蓝本,还可以转换为Java、C#等其他语言。当然转换后的代码不可能100%的可以直接工作,但是可以肯定的是已经完成了99%的工作,就剩下1%一点点的手动修改即可。
关于继承的映射。基类消息作为子类消息的第一个字段,明白字段名称为base;

  1. 数据类型映射规则
编号 C++数据类型 限制 protobuf数据类型 备注
1 bool required bool  
2 (unsigned)  char required uint32  or int32 protobuf 不支持char类型,建议使用int替代
3 (unsigned) short required uint32  or int32 protobuf 不支持short类型,建议使用int替代
4 (unsigned) int required sfixed32 or fixed32  
5 (unsigned) long required sfixed32 or fixed32 建议使用 int替代
6 std::string required bytes bytes可以更好的支持中文,protobuf string只支持asscii
不要使用char * ,char[] 等,使用std::string 替代
7 类对象 required 子message  自定义类,而不是系统类对象,需要包含在同一个文件里面,
再次没有递归处理其他包含的头文件。后续可能支持
类被映射为一个消息(只映射一次)
并再次映射为消息的成员(子消息)
8 指针类型,支持2种指针:
shared_ptr<T>
weak_ptr<T>
optional  根据T的实际类型进行映射 T的类型为上面 编号1~7中的任意一种。
9 集合类型,包含一下几种:
std::vector<T>
std::list<T>
std::set<T>
std::multiset<T>
required
repeated
bool include_${filename}字段
根据T的实际类型进行映射
包含一个bool类型的include字段,用于指示消息传递的过程中是
否包含本字段(protobuf repeated 字段存在二义性
,在消息不包含repeated字段时,究竟时删除还是保留不变)
T的类型为上面 编号1~8中的任意一种。
10 map类型,包含2种:
std::map<KEY,VALUE>
std::multimap<KEY,VALUE>
optional
repeated
repeated
boo include_${filename}
reptead KEY ${filename}_key
reptead VALUE ${filename}_value
KEY和VALUE各自映射为一个字段。在传输过程中,
通过下标一一匹配.
KEY,VALUE的类型为上面 编号1~8中的任意一种。

3. 自动化工具
工具使用Scala BNF语法进行构建,对C++头文件进行词法语法分析(主要分析类的声明和枚举的定义),并提取类的相关信息用于生成代码。
4.工具测试结果。
 4.1 测试内容

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ Class Mapped Google Protocol Buffer Message 的相关文章

随机推荐