操作流程
1)在.proto文件中定义消息格式
2)使用protobuf编译器生成C++类
3)使用C++ API来读写消息
C++编程指导:https://developers.google.com/protocol-buffers/docs/cpptutorial
消息格式
syntax = "proto3"; //指定版本信息,不指定会报错
message Person //message为关键字,作用为定义一种消息类型
{
string name = 1; //姓名
int32 id = 2; //id
string email = 3; //邮件
消息由至少一个字段组合而成,类似于C语言中的结构体,每个字段都有一定的格式:
数据类型 字段名称 = 唯一的编号标签值;
- 字段名称:protobuf建议以下划线命名而非驼峰式
- 唯一的编号标签:代表每个字段的一个唯一的编号标签,在同一个消息里不可以重复。这些编号标签用与在消息二进制格式中标识你的字段,并且消息一旦定义就不能更改。需要说明的是标签在1到15范围的采用一个字节进行编码,所以通常将标签1到15用于频繁发生的消息字段。编号标签大小的范围是1到229。此外不能使用protobuf系统预留的编号标签(19000 ~19999)。
数据类型
.proto类型 | C++类型 | 备注 |
double | double | 64位浮点数 |
float | float | 32位浮点数 |
int32 | int32 | 32位整数 |
int64 | int64 | 64位整数 |
uint32 | uint32 | 32位无符号整数 |
uint64 | uint64 | 64位无符号整数 |
sint32 | int32 | 32位整数,处理负数效率比int32更高 |
sint32 | sint64 | 64位整数,处理负数效率比int64更高 |
fixed32 | uint32 | 总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。 |
fixed64 | uint64 | 总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。 |
sfixed32 | int32 | 总是4个字节 |
sfixed64 | int64 | 总是8个字节 |
bool | bool | 布尔类型 |
string | string | 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本 |
bytes | string | 处理多字节的语言字符、如中文 |
enum | enum | 枚举 |
message | object of class | 自定义的消息类型 |
更多详情请看:https://developers.google.com/protocol-buffers/docs/encoding
proto文件
proto文件即消息协议原型定义文件,在该文件中我们可以通过使用描述性语言,来良好的定义我们程序中需要用到数据格式。
通过查看头文件,可以发现针对每个字段都会大致生成如下几种函数,以name为例:
void clear_name();
void set_name(const ::std::string& value);
void set_name(const char* value);
void set_name(const char* value, size_t size);
const ::std::string& name() const;
::std::string* mutable_name();
可以看出,对于每个字段会生成一个clear清除函数(clear_name)、set函数(set_name)、get函数(name和mutable_name)。
这儿解释下get函数中的两个函数的区别: 对于原型为const std::string &number() const的get函数而言,返回的是常量字段,不能对其值进行修改。但是在有一些情况下,对字段进行修改是必要的,所以提供了一个mutable版的get函数,通过获取字段变量的指针,从而达到改变其值的目的。