1、Protocol Buffer介绍
Protocol Buffer( 简称 Protobuf) 是Google公司内部的混合语言数据标准,它是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,很适合做数据存储或RPC 数据交换格式。
Protobuf是一个纯粹的展示层协议,可以和各种传输层协议一起使用,Protobuf的文档也非常完善。google 提供了多种语言的实现:java、c#、c++、go 和 python,每一种实现都包含了相应语言的编译器以及库文件。
Protobuf支持的数据类型相对较少,不支持常量类型。由于其设计的理念是纯粹的展现层协议,目前并没有一个专门支持Protobuf的RPC框架。
2、Protobuf使用流程
2.1 准备数据
- 复合类型: 结构体/ 类
-
要序列化的数据
- 基础类型
-
// 要序列化的数据
struct Persion
{
int id;
string name;
int age;
};
int id;
2.2、创建.proto文件,语法格式
// protobuf的版本
// proto2
syntax = "proto3";
// 导入另外一个proto文件
import "filename.proto";
// 组织Persion结构体
// 语法格式
message 关键字(相当于被创建出的类的名字)
{
// 成员变量
数据类型 变量名 = 变量的编号; // 编号从1开始, 不能重复
}
- repeated限定修饰符(使用数组)
- 使用import导入另外一个proto文件
- 使用package添加命名空间
- 示例
// Persion.proto
syntax = "proto3";
// 导入另外一个proto文件
import "Info.proto";
// 添加命名空间
package namespace; // Persion类属于namespace这个命名空间
enum TypeValue
{
value1 = 0; // protbuf中第一个枚举值必须为0
value2 = 6;
value3 = 9;
}
message Persion
{
int32 id = 1; // 编号从1开始
repeated bytes name = 2; //repeated修饰name可以在程序中创建多个, 在程序中作为动态数组来使用
int32 age = 3;
TypeValue value = 4;
Info info = 5; // Info对象, 导入的proto文件中的类
}
// Info.proto
syntax = "proto3";
// 添加命名空间
package namespace; // Persion类属于namespace这个命名空间
message Info
{
bytes address = 1;
int32 number = 2;
}
- .proto数据类型
.proto类型 | C++类型 | 备注 |
---|---|---|
double | double | 64位浮点数 |
float | float | 32位浮点数 |
int32 | int32 | 32位整数 |
int64 | int64 | 64位整数 |
uint32 | uint32 | 32位无符号整数 |
uint64 | uint64 | 64位无符号整数 |
sint32 | sint32 | 32位整数,处理负数效率比int32更高 |
sint64 | 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 | 自定义的消息类型 |
2.2、使用protobuf编译器生成C++类
# protobuf编译器, 编译源码得到的 protoc.exe
# 语法
# --cpp_out 生成的c++类的位置
protoc.exe xxx.proto --cpp_out=目录
2.3、使用C++ API来读写消息
-
读:
变量名()
-
写:
set_变量名(arg1, arg2, ...)
- 部分C++接口函数
Person p;
//序列化 output为传出参数
p.SerializeToString(std::string* output);
//解析
Person pp;
pp.ParseFromString(output);
2.4、VS中的使用
- 将生成的C++类和头文件添加到项目
- 在项目文件中的头文件中引用
- 注意:VS配置需要在C/C++-》预处理器-》添加宏"PROTOBUF_USE_DLLS"