当前位置: 首页 > article >正文

【protobuf(1)】首次理解与实践

Protobuf是Protocol Buffers的简称,它是Google公司开发的一种数据描述语言,是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化 。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 三种语言的 API。

  • protobuf是类似与json一样的数据描述语言(数据格式)
  • protobuf非常适合于RPC数据交换格式

注意:protobuf本身并不是和gRPC绑定的。它也可以被用于非RPC场景,如存储等

protobuf的优劣势

1)优势:

  • 序列化后体积相比Json和XML很小,适合网络传输
  • 序列化反序列化速度很快,快于Json的处理速度
  • 消息格式升级和兼容性还不错
  • 支持跨平台多语言

2)劣势:

  • 应用不够广(相比xml和json)
  • 二进制格式导致可读性差
  • 缺乏自描述

如何实现序列化?

主流的序列化和反序列化工具有:XML、JSON、ProtoBuf;

ProtoBuf工作特点

通过Protobuf编译器,可以将.proto后缀的数据结构文件编译成各编程语言专用的类文件,简化了序列化和反序列化的过程。

  • 我们使用ProtoBuf的编译器来编译这个.proto文件,就会得到一个.cpp和.hpp的文件
  • 在我们的工作代码中包含以下ProtoBuf编译出来的.cpp和.hpp文件就可以了

Protobuf与DDS的关系

在分布式系统中,Protobuf和DDS经常结合使用,以优化数据传输效率和可靠性。具体来说,它们之间的关系体现在以下几个方面:

  • 数据序列化:Protobuf用于定义和序列化数据,生成紧凑的二进制格式。这种格式的数据可以高效地通过网络传输,并减少带宽占用。
  • DDS通信:DDS作为中间件,负责在分布式节点之间传输数据。通过DDS的发布-订阅模型,节点可以灵活地订阅和发布数据,而无需关心数据的具体传输过程。
  • 集成使用:在ROS2(Robot Operating System 2)等分布式机器人操作系统中,Protobuf和DDS被紧密集成。Protobuf用于定义消息结构,而DDS则负责这些消息的传输。通过编写适配器或自定义middleware层,可以将Protobuf消息转换为DDS可理解的格式,并在DDS网络中传输。

快速上手

在快速上⼿中,将实现:
• 对⼀个联系⼈的信息使⽤ProtoBuf进⾏序列化,并将结果打印出来.
• 对序列化后的内容使⽤ProtoBuf进⾏反序列,解析出联系⼈信息并打印出来。

步骤1 创建proto文件

  1. 创建一个.proto文件:
    这里我们创建一个PeopleInfo.proto文件,需要完成:
  • 初始化工作,比如:指定PB语法版本、为当前.proto文件中的数据指定作用域; 当前.proto文件所采用的语法版本为"proto3"的版本,默认采用proto2语法进行编译,但是 proto2语法支持上没有proto3广。
  • 定义的类声明一个命名空间,来避免不同 .proto之间的命名冲突的问题; 这个命名空间的定义并不是强制的,编译过后会变为C++中的namespace 命名空间。
  • 定义类了,在.proto文件中定义类是利用message 关键字来完成的,在message 定义的类中,我们只需要定义出该类所包含的属性即可,同时我们需要给这些属性进行编号,并且每个同级属性之间不能重复,这是PB语法要求的;
    在这里插入图片描述

同时编号也不是随便乱设的,编号也是有范围的,编号只能从1 ~ 2^29 -1之间进行取数,其中19000 ~ 19999不可取,因为这些编号已经被PB官方征用了!使用了编译就会出错; 在字段命名上,我们也是要注意一点规范,比如使用全小写字母、多个字母之间使用下划线连接;

PB中那些标量类型,与C++中的那些类型相对应:

.proto TypeNotesC++ Type
doublenulldouble
floatnullfloat
int32使用变成编码。负数的编码效率比较低(若字段出现负数的频率比较高,可以考虑使用sint32代替)int32
int64使用变长编码。负数的编码效率比较低(若字段出现负数的频率比较高,可以考虑使用sint64代替)int64
uint32使用变长编码uint32
uint64使用变长编码uint64
sint32使用变长编码。符号整型。负数编码效率高于常规int32int32
sint64使用变长编码。符号整型。负数编码效率高于常规int64int64
fixed32定长4字节。若值常大于2^28则会比uint32更高效uint32
fixed64定长8字节。若常值大于2^28则会比uint64更高效uint64
sfixed32定长4字节int32
sfixed64定长8字节int64
boolnullbool
string包含UTF-8和ASCII编码的字符串,长度不能超过2^32string
bytes可以包含任意的字节序列但长度不能超过2^32string

步骤2:编译PeopleInfo.proto文件形成对应的C++文件;

protoc [-I] --xxx_out=OUT_DIR file.proto
-I :表示指定被编译的.proto文件所在目录,可多次指定,用空格隔开;若不指定则默认在当前路径下进行搜索;
–xxx_out: 将.proto文件编译成那种编程语言的文件;eg:--cpp_out将.proto文件编译成C++文件、 --java_out=将.proto文件编译成java文件、 --csharp_out=将.proto文件编译成C#文件等
OUT_DIR: 编译完成过后的文件所存放的路径;

举例:
protoc -I test1/ --cpp_out=./test1/ PeopleInfo.proto

/在test1目录下检索PeopleInfo.proto文件,然后将其编译成C++文件,将该C++文件放在test1/目录下;(指定检索目录的情况)

步骤3:在c++ 中引用

我们的目的是将一个联系人的信息进行序列化,然后打印序列化结果,然后再反序列化,打印出反序列化的结果。编译代码记得链接 protobuf 库。
在这里插入图片描述

参考

https://blog.csdn.net/Gefangenes/article/details/131319610
https://blog.csdn.net/qq_62106937/article/details/134095333


http://www.kler.cn/a/374204.html

相关文章:

  • 《高频电子线路》 —— 高频谐振功放(2)
  • Python飞舞蝙蝠
  • 算法定制LiteAIServer视频智能分析软件的过亮、过暗及抖动检测应用场景
  • OpenCV 学习笔记
  • 前端代码注释
  • 链接动态库
  • Linux中NFS配置
  • np.expand_dims函数
  • 校园社团信息管理:Spring Boot技术的应用与优化
  • RHCE 配置文件
  • 今日总结10.31
  • 基于RMBG大模型的AI抠图证件照换背景带GUI
  • 功能强大视频编辑软件 Movavi Video Editor Plus 2024 v24.2.0 中文特别版
  • 玩转Docker | Docker基础入门与常用命令指南
  • Flutter学习笔记(一)-----环境配置
  • ADB指定进程名称kill进程
  • Chromium127编译指南 Linux篇 - 额外环境配置(五)
  • word试题转excel(最简单的办法,无格式要求)
  • 【C++题解】1187. 数字走向IV
  • 曹操出行借助 ApsaraMQ for Kafka Serverless 提升效率,成本节省超 20%
  • 【ChatGPT】让ChatGPT为特定行业编写专业报告
  • 使用二进制安装K8S 多master节点 高可用集群
  • 高效集成:YS采购订单与帆软MongoDB的对接实践
  • 计算机视觉实验二:图像滤波
  • 如何在Linux系统中使用Git进行版本控制
  • 在Bash脚本中 set -e 是什么意思