C++工程,protobuf初识,读prototxt文件,下载安装,消息结构体详解,编译命令

1,下载安装包

https://github.com/protocolbuffers/protobuf/releases/latest

For example: if you only need C++, download `protobuf-cpp-[VERSION].tar.gz`; if
you need C++ and Java, download `protobuf-java-[VERSION].tar.gz` (every package
contains C++ source already); if you need C++ and multiple other languages,
download `protobuf-all-[VERSION].tar.gz`.

在这里插入图片描述

2,解压安装

$ tar -vxf protobuf-cpp-3.8.0.tar.gz
$ cd protobuf-3.8.0/ 
$ ./configure
$ make
$ make check
$ sudo make install
$ sudo ldconfig # refresh shared library cache.

2.1,查看版本

$ protoc --version

3,使用

https://www.jianshu.com/p/419efe983cb2

枚举类为什么有0
https://blog.csdn.net/skh2015java/article/details/78404235

https://blog.csdn.net/hry2015/article/details/70766603

https://www.cnblogs.com/zhouyang209117/p/7218719.html

https://blog.csdn.net/yang332233/article/details/83657735

3.1,定义数据结构体---编写config.proto

// 指定版本号为proto3; 否则默认使用proto2
// 注意:版本号指定必须放在第一行
syntax = "proto3";

// 包名,用来防止Protocol Buffers name space里的名字冲突 
package config;

// 引入外部的proto对象
import "google/protobuf/any.proto";

// 生成java文件后的包名
option java_package = "com.hry.spring.proto.complex";
option java_outer_classname = "MyComplexObjectEntity";

message ComplexObject {  
    // Message里每个成员变量都有一个唯一的数字标志(   Assigning Tags)
    int32 id = 1;//  singular, 默认值,表示成员只有0个或者1个
    string name = 2;// 
    string email = 3;//
    repeated string sons = 4; // repeated 列表
    Gender gender = 5; // Enum值
    repeated Result result = 6; // 新的对象List
    repeated google.protobuf.Any any = 7; // Any对象
    map<string, MapVaule> map = 8; // 定义Map对象

    // reserved
    reserved 12, 15, 9 to 11; // 预留将来使用的Assigning Tags,
    reserved "foo", "bar"; // 预留将来使用的filed name
} 

enum Gender {
  // option allow_alias = true;
  MAN = 0;
  WOMAN = 1;
}

// 定义一个新的对象
message Result {
  string url = 1;
  string title = 2;
  repeated string snippets = 3;
}

// 定义Map的value值
message MapVaule {
  string mapValue = 1;
}

3.1.1,一个字段由以下部分组成:

规则 类型 字段名=标识号; [// 注释]

3.1.1.1,指定字段规则

所指定的消息字段修饰符必须是如下之一:

required 一个格式良好的消息一定要含有1个这种字段。表示该值是必须要设置的
optional 消息格式中该字段可以有0个或1个值(不超过1个)
repeated 在一个格式良好的消息中,这种字段可以重复任意多次(包括0次)。重复的值的顺序会被保留。表示该值可以重复,相当于java中的List

由于一些历史原因,基本数值类型的repeated的字段并没有被尽可能地高效编码。在新的代码中,用户应该使用特殊选项[packed=true]来保证更高效的编码。如:
repeated int32 samples = 4 [packed=true];
required是永久性的:在将一个字段标识为required的时候,应该特别小心。如果在某些情况下不想写入或者发送一个required的 字段,将原始该字段修饰符更改为optional可能会遇到问题——旧版本的使用者会认为不含该字段的消息是不完整的,从而可能会无目的的拒绝解析。在这 种情况下,你应该考虑编写特别针对于应用程序的、自定义的消息校验函数。Google的一些工程师得出了一个结论:使用required弊多于利;他们更 愿意使用optional和repeated而不是required。当然,这个观点并不具有普遍性。

3.1.1.2,指定字段类型

在上面的例子中,所有字段都是标量类型:两个整型(page_number和result_per_page),一个string类型(query)。当然,你也可以为字段指定其他的合成类型,包括枚举(enumerations)或其他消息类型。
一个标量消息字段可以含有一个如下的类型——该表格展示了定义于.proto文件中的类型,以及与之对应的、在自动生成的访问类中定义的类型:
在这里插入图片描述

3.1.1.3,分配标识号

正如上述文件格式,在消息定义中,每个字段都有唯一的一个标识符。这些标识符是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改 变。注:[1,15]之内的标识号在编码的时候会占用一个字节。[16,2047]之内的标识号则占用2个字节。所以应该为那些频繁出现的消息元素保留 [1,15]之内的标识号。切记:要为将来有可能添加的、频繁出现的标识号预留一些标识号。
最小的标识号可以从1开始,最大到229 - 1, or 536,870,911。不可以使用其中的[19000-19999]的标识号, Protobuf协议实现中对这些进行了预留。如果非要在.proto文件中使用这些预留标识号,编译时就会报警。

3.1.1.4,添加注释

向.proto文件添加注释,可以使用C/C++/java风格的双斜杠(//) 语法格式,如:

3.1.2,从.proto文件生成了什么?

语言产生文件
C++ 编译器会为每个.proto文件生成一个.h文件和一个.cc文件,.proto文件中的每一个消息有一个对应的类。
Java 编译器为每一个消息类型生成了一个.java文件,以及一个特殊的Builder类(该类是用来创建消息类接口的)。
Python 有点不太一样——Python编译器为.proto文件中的每个消息类型生成一个含有静态描述符的模块,,该模块与一个元类(metaclass)在运行时(runtime)被用来创建所需的Python数据访问类。
go 编译器会位每个消息类型生成了一个.pd.go文件。
Ruby 编译器会为每个消息类型生成了一个.rb文件。
javaNano 编译器输出类似域java但是没有Builder类
Objective-C 编译器会为每个消息类型生成了一个pbobjc.h文件和pbobjcm文件,.proto文件中的每一个消息有一个对应的类。
C# 编译器会为每个消息类型生成了一个.cs文件,.proto文件中的每一个消息有一个对应的类。

3.1.3,枚举

如你所见,Corpus枚举的第一个常量映射为0:每个枚举类型必须将其第一个类型映射为0,这是因为:
必须有有一个0值,我们可以用这个0值作为默认值。
这个零值必须为第一个元素,为了兼容proto2语义,枚举类的第一个值总是默认值。
你可以通过将不同的枚举常量指定位相同的值。如果这样做你需要将allow_alias设定位true,否则编译器会在别名的地方产生一个错误信息。

3.2,使用protoc编译器进行编译

//SRC_DIR   .proto文件存放目录
//--cpp_out  指示编译器生成C++代码,DST_DIR为生成文件存放目录
//game.proto 待编译的协议文件
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/game.proto

3.2.1,导出C++包

protoc --cpp_out=./ config.proto

报错:

[libprotobuf WARNING google/protobuf/compiler/parser.cc:637] No syntax specified for the proto file: config.proto. Please use 'syntax = "proto2";' or 'syntax = "proto3";' to specify a syntax version. (Defaulted to proto2 syntax.)

在这里插入图片描述

3.2.2,导出java包

protoc  --java_out=./ ./config.proto

在这里插入图片描述

3.2.3,导出python包

protoc  --python_out=./ ./config.proto

在这里插入图片描述

3.3,编译代码

g++ -std=c++11 addressbook.pb.cc write_data.cpp -o write_data.out -lprotobuf `pkg-config --cflags --libs protobuf`
g++ -std=c++11 addressbook.pb.cc read_data.cpp -o read_data.out -lprotobuf `pkg-config --cflags --libs protobuf`
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值