Protobuf: 初识

protobuf是什么

简单来讲,ProtoBuf(全称为ProtocolBuffer)是让结构数据序列化的⽅法,其具有以下特点:
语⾔⽆关、平台⽆关:即ProtoBuf⽀持Java、C++、Python等多种语⾔,⽀持多个平台。
⾼效:即⽐XML更⼩、更快、更为简单。
扩展性、兼容性好:你可以更新数据结构,⽽不影响和破坏原有的旧程序。

使用特点

ProtoBuf是需要 依赖通过编译⽣成的头⽂件和源⽂件来使⽤的。
也就是说,写一份.proto后缀的文件,再用相应的编译规则去编译,可以生成不同语言的代码。

位置:

/usr/local/protobuf/include/google/protobuf/

通讯录1.0

1.创建一份.proto文件
1.命名规范:
  • 创建.proto⽂件时,⽂件命名应该使⽤全⼩写字⺟命名,多个字⺟之间⽤ _ 连接。例如:lower_snake_case.proto 。
  • 书写.proto⽂件代码时,应使⽤2个空格的缩进。
我们为通讯录1.0新建⽂件: contacts.proto
指定proto3语法:
syntax = "proto3" proto3语法是最新的语法版本,更简化,易于使用,支持更多语言的生成。
package声明符:
package能表⽰.proto⽂件的 命名空间,在项⽬中要有唯⼀性。它的作⽤是为了避免我们定义的消息出现冲突。
2.定义消息(message):
消息(message):要定义的结构化对象,我们可以给这个结构化对象中定义其对应的属性内容。
定义消息字段:
在message中我们可以定义其属性字段,字段定义格式为: 字段类型 + 字段名=字段唯⼀编号;
  • 字段名称命名规范:全⼩写字⺟,多个字⺟之间⽤_连接。
  • 字段类型分为:标量数据类型和特殊类型(包括枚举、其他消息类型等)。
  • 字段唯⼀编号:⽤来标识字段,⼀旦开始使⽤就不能够再改变。
.proto TypeNotesc++ Type
doubledouble
floatfloat
int32使⽤变⻓编码[1]。负数的编码效率较低⸺若字段可能为负值,应使⽤sint32代替int32
int64使⽤变⻓编码[1]。负数的编码效率较低⸺若字段可
能为负值,应使⽤sint64代替
int64
uint32使用变长编码[1]uint32
uint64使用变长编码[1]uint64
sint32使⽤变⻓编码[1]。符号整型。负值的编码效率⾼于
常规的int32类型
sint32
sint64使⽤变⻓编码[1]。符号整型。负值的编码效率⾼于
常规的int64类型
sint64
fixed32定⻓4字节。若值常⼤于2^28则会⽐uint32更⾼
uint32
fixed64定⻓8字节。若值常⼤于2^56则会⽐uint64更⾼效uint64
sfixed32定⻓4字节int32
sfixed64定⻓8字节int64
boolbool
string包含UTF-8和ASCII编码的字符串,⻓度不能超过2^32string
bytes可包含任意的字节序列但⻓度不能超过2^32string

[1]变⻓编码:经过protobuf编码后,原本4字节或8字节的数可能会被变为其他字节数

在这⾥还要特别讲解⼀下字段唯⼀编号的范围:
1~536,870,911(2^29-1),其中19000?~19999不可⽤。
19000~19999不可⽤是因为:在Protobuf协议的实现中,对这些数进⾏了预留。
值得⼀提的是,范围为1~15的字段编号需要⼀个字节进⾏编码,16~2047内的数字需要两个字节进⾏编码。编码后的字节不仅只包含了编号,还包含了字段类型。所以 1~15要⽤来标记出现⾮常频繁的字段,要为将来有可能添加的、频繁出现的字段预留⼀些出来。
3.编译命令
编译命令⾏格式为:
protoc [--proto_path=IMPORT_PATH] --cpp_out=DST_DIR path/to/file.proto
protoc 是 Protocol Buffer 提供的命令⾏编译⼯具。
2.编译contacts.proto⽂件后会⽣成什么
  • 对于每个message,都会⽣成⼀个对应的消息类。
  • 在消息类中,编译器为每个字段提供了获取和设置⽅法,以及⼀下其他能够操作字段的⽅法。
  • 编辑器会针对于每个 .proto⽂件⽣成 .h 和 .cc⽂件,分别⽤来存放类的声明与类的实现
3.常用的序列化,反序列化方法
class MessageLite {
public:
//序列化:
bool SerializeToOstream(ostream* output) const; // 将序列化后数据写⼊⽂件
流
bool SerializeToArray(void *data, int size) const;
bool SerializeToString(string* output) const;
//反序列化:
bool ParseFromIstream(istream* input); // 从流中读取数据,再进⾏反序列化
动作
bool ParseFromArray(const void* data, int size);
bool ParseFromString(const string& data);
};
注意:protobuf序列化出来的是二进制,放到String里打印会有误差,破解成本增⼤,所以ProtoBuf编码是相对安全的。
4.字段类型的规则
消息的字段可以⽤下⾯⼏种规则来修饰:
  • singular:消息中可以包含该字段零次或⼀次(不超过⼀次)。proto3语法中,字段默认使⽤该规则。
  • repeated:消息中可以包含该字段任意多次(包括零次),其中重复值的顺序会被保留。可以理解为定义了⼀个数组。
下面是contacts.proto
  //首行写使用语法syntax = "proto3";package contacts;message PeopleInfo{string name = 1; //编号int32 age = 2;}
下面是main.cc
#include <iostream>
#include "contacts.pb.h"
#include <string>int main()
{std::string str;contacts::PeopleInfo person;person.set_name("张三");person.set_age(20);bool ret = person.SerializeToString(&str);if (ret == false)std::cout << "序列化失败" << std::endl;std::cout << "序列化成功,str: " << str << std::endl;{contacts::PeopleInfo person;bool ret = person.ParseFromString(str);if (ret == false)std::cout << "反序列化失败" << std::endl;std::cout << "反序列化成功" << std::endl;std::cout << "name: " << person.name() << std::endl;std::cout << "age: " << person.age() << std::endl;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/64476.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS 语法

CSS 语法 CSS(层叠样式表)是一种用于描述HTML或XML文档样式的样式表语言。它允许您将样式信息与文档内容分离,从而更有效地控制网页的布局和外观。本文将详细介绍CSS的基本语法和结构,帮助您更好地理解和应用CSS。 CSS的基本结构 CSS由一系列的规则组成,每个规则包含一…

Vue3安装配置、开发环境搭建(组件安装卸载)(图文详细)

Vue3安装配置、开发环境搭建(组件安装卸载)&#xff08;图文详细&#xff09; 本文目录&#xff1a; 一、vue的主要安装使用方式 二、node.js安装和配置 1、支持运行 Node.js的平台 2、Node.js 版本开发发布时间表&#xff08;日期可能会有变化&#xff09; 3、下载安装n…

Oracle 适配 OpenGauss 数据库差异语法汇总

背景 国产化进程中&#xff0c;需要将某项目的数据库从 Oracle 转为 OpenGauss &#xff0c;项目初期也是规划了适配不同数据库的&#xff0c;MyBatis 配置加载路径设计的是根据数据库类型加载指定文件夹的 xml 文件。 后面由于固定了数据库类型为 Oracle 后&#xff0c;只写…

Vue进阶之状态管理,解锁项目开发超能力

一、概念 状态管理是指对应用程序中状态的管理。在软件领域&#xff0c;状态是指在某个特定时刻&#xff0c;应用程序的数据和行为表现。 以一个简单的购物网站为例&#xff0c;购物车中的商品列表、用户的登录状态等都是状态。状态管理主要涉及这些状态如何被存储、更新和在…

操作系统(16)I/O软件

前言 操作系统I/O软件是负责管理和控制计算机系统与外围设备&#xff08;例如键盘、鼠标、打印机、存储设备等&#xff09;之间交互的软件。 一、I/O软件的定义与功能 定义&#xff1a;I/O软件&#xff0c;也称为输入/输出软件&#xff0c;是计算机系统中用于管理和控制设备与主…

WPF+MVVM案例实战与特效(四十二)- 打造炫酷彩虹字体控件,让你的应用闪耀起来

文章目录 1、引言2、案例实现1、依赖属性2、代码解释3、转换器实现3、控件使用4、运行效果4、总结1、引言 在WPF 应用程序中,视觉效果往往是吸引用户注意力的关键。一个小小的字体控件,如果能够以彩虹般的色彩展示文本,不仅能让界面更加生动,还能为用户提供独特的交互体验…

游戏AI实现-寻路算法(Dijkstra)

戴克斯特拉算法&#xff08;英语&#xff1a;Dijkstras algorithm&#xff09;&#xff0c;又称迪杰斯特拉算法、Dijkstra算法&#xff0c;是由荷兰计算机科学家艾兹赫尔戴克斯特拉在1956年发现的算法。 算法过程&#xff1a; 1.首先设置开始节点的成本值为0&#xff0c;并将…

CTFshow-文件上传(Web151-170)

CTFshow-文件上传(Web151-170) 参考了CTF show 文件上传篇&#xff08;web151-170&#xff0c;看这一篇就够啦&#xff09;-CSDN博客 Web151 要求png&#xff0c;然后上传带有一句话木马的a.png&#xff0c;burp抓包后改后缀为a.php&#xff0c;然后蚁剑连接&#xff0c;找fl…

Unity超优质动态天气插件(含一年四季各种天气变化,可用于单机局域网VR)

效果展示&#xff1a;https://www.bilibili.com/video/BV1CkkcYHENf/?spm_id_from333.1387.homepage.video_card.click 在你的项目中设置enviro真的很容易&#xff01;导入包裹并按照以下步骤操作开始的步骤&#xff01; 1. 拖拽“EnviroSky”预制件&#xff08;“environme…

Windows环境下安装和使用Open Interpreter(没有OpenAI API key也可以运行)

文章目录 Open Interpreter简介安装运行本地模型运行model i退出 Open Interpreter简介 相比于其他的模型&#xff0c;Open Interpreter最大的亮点就是能够在模型上直接自动运行和调试代码。而其他的模型则需要在生成代码之后&#xff0c;复制到对应的本地IDE上运行、调试。如…

Python列表推导式:嵌套用法详解

Python列表推导式&#xff1a;嵌套用法详解 1. 什么是列表推导式&#xff1f;举个例子&#xff1a; 2. 什么是嵌套列表推导式&#xff1f;举个例子&#xff1a; 3. 嵌套列表推导式的语法再来一个例子&#xff1a; 4. 嵌套列表推导式的高级用法4.1 生成矩阵4.2 过滤嵌套列表4.3 …

Ubuntu如何下载nvidia驱动和Cuda Toolkit

Ubuntu如何下载nvidia驱动和Cuda Toolkit 前言 ‍ 手快不小心把 nvidia​ 的某个东西删除了&#xff0c;现在不得不全部卸载后再重新安装了。 我再也不敢在不确认内容的情况下&#xff0c;确认删除了… ‍ Note: ‍ 笔者环境为 Ubuntu 24.04LTS​ ‍ ‍ 目录 ‍ 文章…

Ubuntu系统安装MySQL

使用在线方式安装 更新软件包 sudo apt update安装MySQL服务器 # 查看可使用的安装包 sudo apt search mysql-server安装指定版本的MySQL # 安装指定版本 sudo apt install -y mysql-server-8.0如果不加-y 会在安装过程中&#xff0c;系统将提示你设置MySQL的root密码。记住…

最大质因子序列

最大质因子序列 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 任意输入两个正整数m, n (1 < m < n < 5000)&#xff0c;依次输出m到n之间每个数的最大质因子&#xff08;包括m和n&#xff1b;…

C语言中信号量:<semaphore.h>头文件

<semaphore.h> 是一个 POSIX 标准定义的头文件&#xff0c;用于提供信号量&#xff08;semaphore&#xff09;的接口。信号量是用于线程或进程间同步的一种机制&#xff0c;可以控制访问共享资源的线程数目&#xff0c;广泛应用于多线程和多进程编程。 本文将详细介绍 &…

Netcat:网络中的瑞士军刀

免责声明&#xff1a;使用本教程或工具&#xff0c;用户必须遵守所有适用的法律和法规&#xff0c;并且用户应自行承担所有风险和责任。 文章目录 一、引言二、简述三、Netcat功能&#xff1f;四、参数选项五、Netcat 的常见功能六、高级用法多连接处理创建简单的代理 七、Netc…

GhostRace: Exploiting and Mitigating Speculative Race Conditions-记录

文章目录 论文背景Spectre-PHT&#xff08;Transient Execution &#xff09;Concurrency BugsSRC/SCUAF和实验条件 流程Creating an Unbounded UAF WindowCrafting Speculative Race ConditionsExploiting Speculative Race Conditions poc修复 论文 https://www.usenix.org/…

Spring Boot 中使用 Mybatis Plus

Spring Boot 中使用 Mybatis Plus 在现代的企业级开发中&#xff0c;MyBatis Plus 是 MyBatis 的增强工具&#xff0c;它简化了很多常见的数据库操作。通过 Spring Boot 集成 MyBatis Plus&#xff0c;可以快速构建高效、简洁的数据库操作层。本文将介绍如何在 Spring Boot 项…

LeetCode:209. 长度最小的子数组(滑动窗口 Java)

目录 209. 长度最小的子数组 题目描述&#xff1a; 实现原理与解析&#xff1a; 滑动窗口 原理思路&#xff1a; 209. 长度最小的子数组 题目描述&#xff1a; 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的…

【SpringBoot 调度任务】

在 Spring Boot 中实现调度任务&#xff08;Scheduled Tasks&#xff09;&#xff0c;通过使用 EnableScheduling 和 Scheduled 注解来完成。 添加依赖启用调度任务支持创建调度任务运行应用程序 添加依赖 pom.xml 文件中有以下依赖项&#xff1a; <dependency><gro…