介绍
通俗点说,就是将要发送的消息,通过protobuf格式发出去,自动进行封装。另一方对proto格式解析,直接得到原数据。
protocol buffers是什么?
是一种结构数据序列化方法, 可类比XML。 定义数据的结构 > 生成的源代码(.proto文件) -> 在数据流中&各种语言进行编写, 读取结构数据。
如何使用
- 定义.proto文件, 来定义你的数据结构;(消息格式文件)中定义 protocol buffer message 类型, 来指定你想如何对序列化信息进行结构化。 message 包含name-value对, 可嵌套。
缺省默认就设置为 optional
创建 .proto 文件,定义数据结构
message xxx {
// 字段规则:required -> 字段只能也必须出现 1 次 // 字段规则:optional -> 字段可出现 0 次或1次 // 字段规则:repeated -> 字段可出现任意多次(包括 0) // 类型:int32、int64、sint32、sint64、string、32-bit .... // 字段编号:0 ~ (除去 19000 到 19999 之间的数字) 字段规则 类型 名称 = 字段编号; }
注:
1) message 定义中的每个字段都有唯一编号。 2) 单个 .proto 文件中定义多种 message 类型 3) message内可嵌套message 4) .proto 文件添加注释,可以使用 C/C++ 语法风格的注释 // 和 /* ... */
- 使用protoc编译器进行编译,导出c++代码。
我们在 .proto 文件中定义了数据结构,这些数据结构是面向开发者和业务程序的,并不面向存储和传输。
当需要把这些数据进行存储或传输时,就需要将这些结构数据进行序列化、反序列化以及读写。那么如何实现呢?不用担心,ProtoBuf 将会为我们提供相应的接口代码。如何提供?答案就是通过 protoc 这个编译器。
可通过如下命令生成相应的接口代码:
// $SRC_DIR: .proto 所在的源目录 // --cpp_out: 生成 c++ 代码 // $DST_DIR: 生成代码的目标目录 // xxx.proto: 要针对哪个 proto 文件生成接口代码 protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto
- 使用c++的api进行数据的读写()。
person结构体举例:
message Person {
required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType {
MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber {
required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; }
一个例子
创建.proto文件
message Example1 {
optional string stringVal = 1; optional bytes bytesVal = 2; message EmbeddedMessage {
int32 int32Val = 1; string stringVal = 2; } optional EmbeddedMessage embeddedExample1 = 3; repeated int32 repeatedInt32Val = 4; repeated string repeatedStringVal = 5; }
调用生成接口, 进行序列化操作
#include
#include
#include
#include "single_length_delimited_all.pb.h" int main() {
Example1 example1; example1.set_stringval("hello,world"); example1.set_bytesval("are you ok?"); Example1_EmbeddedMessage *embeddedExample2 = new Example1_EmbeddedMessage(); embeddedExample2->set_int32val(1); embeddedExample2->set_stringval("embeddedInfo"); example1.set_allocated_embeddedexample1(embeddedExample2); example1.add_repeatedint32val(2); example1.add_repeatedint32val(3); example1.add_repeatedstringval("repeated1"); example1.add_repeatedstringval("repeated2"); std::string filename = "single_length_delimited_all_example1_val_result"; std::fstream output(filename, std::ios::out | std::ios::trunc | std::ios::binary); if (!example1.SerializeToOstream(&output)) {
std::cerr << "Failed to write example1." << std::endl; exit(-1); } return 0; }
.proto 模板
比如新建xxx.proto
syntax = "proto2"; package xxx.person; # 该.proto产生的类会被封装在xxx::person命名空间中 import "yyy.proto"; # 引用其他的.proto message student {
}
常见问题
- 出现 [libprotobuf WARNING google/protobuf/compiler/parser.cc:648] No syntax specified for the proto file: example.proto. Please use ‘syntax = “proto2”;’ or ‘syntax = “proto3”;’ to specify a syntax version. (Defaulted to proto2 syntax.)
解决:在开头写入: syntax = “proto2”;
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/225833.html原文链接:https://javaforall.net
