一.什么是protobuf?
protobuf是结构化数据序列化和反序列化的框架,特点如下:
- 和语言无关,支持C++,Java,Python等多种语言
- 扩展性好,可以更新结构化数据而不影响原有的代码
二.protobuf使用流程
- 编写.proto文件,使用protobuf的语法定义message(即C++中的类),描述对象中有哪些成员,成员的类型是什么
- 使用protobuf提供的工具翻译.proto文件,形成对应语言的源文件和头文件,其中包含了所需的结构化对象的类,以及对结构化对象的访问,操作,序列化和反序列化方法
- 在我们自己的代码中引入头文件即可使用
三.示例
1.编写.proto文件
在 .proto 文件中,要使用 syntax = "proto3"; 来指定文件语法为 proto3,并且必须写在除去注释内容的第一行。 如果没有指定,编译器会使用proto2语法。
package 是⼀个可选的声明符,能表示 .proto文件的命名空间,将来翻译生成的class也是在该命名空间中在项目中,它的作用是为 了避免我们定义的消息出现冲突。
proto文件中定义⼀个消息类型的格式为:
message 消息类型名
{
}
消息类型命名规范:使用驼峰命名法,首字母大写。
在 message 中我们可以定义其属性字段,字段定义格式为:字段类型 字段名 = 字段唯⼀编号
字段唯⼀编号用来标识字段(供翻译工具使用)⼀旦开始使用就不能够再改变
contacts.proto :
syntax = "proto3"; //声明语法版本
package contacts; //定义命名空间,将来翻译后生成的类,就是在这个命名空间中
//结构化对象的描述
message contacts
{
//字段类型 字段名 = 唯一编号
string name = 1;
float score = 2;
}
2.翻译.proto文件
protoc [--proto_path=IMPORT_PATH] --cpp_out=DST_DIR path/to/file.proto
如:protoc --cpp_out=. contacts.proto
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);
};
- 序列化的结果为二进制字节序列,而非文本格式。
- 以上三种序列化的方法法没有本质上的区别,只是序列化后输出的格式不同,可以供不同的应⽤场景
- 序列化的 API 函数均为const成员函数,因为序列化不会改变类对象的内容, 而是将序列化的结果保存到函数指定的地址中