博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
protobuf
阅读量:6419 次
发布时间:2019-06-23

本文共 2927 字,大约阅读时间需要 9 分钟。

hot3.png

编译安装

        http://www.cnblogs.com/javaee6/p/4849051.html

使用

其实用法非常简单(暂时没有涉及到tcp的封包等问题):

1 proto文件的语法

主要的模板如下:

package tutorial; 这个包名会成为一个名字空间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;}message AddressBook {    repeated Person person = 1;}

以上的proto文件用protoc命令生成一个.h文件和一个.cc文件,这两个文件就是生成的类的定义。

注意:

required 规定必须提供字段,否则message就是没有初始化的。

optional 可以设置,也可以不设置字段。不设置字段时会使用默认值,可以指定可选字段的默认值。

     如果没有指定默认值,则对于数值类型,0是默认值;

     对于字符串,空字符串是默认值;

     对于bool类型,false是默认值;

     对于嵌入的message类型,默认值是此message的默认实例或者元类型,其中每个字段都没有设置。

     对于没有显示设定值的可选或者必选字段,调用访问器总是返回字段的默认值。

repeated 定义字段可以重复多次(包括0次)。各个重复的值的次序会保留,可以把重复字段看作是动态数组。

 

protoc -I=./ --cpp_out=./ XXXXXXXXXXXX.proto其中-I指定的是proto文件所在的路径,--cpp_out是指定生成的c++类定义文件的路径,最后那个.proto指定的是具体的编写的proto文件的名称。

2 生成的类的定义与接口详解

每个mesage的生成的类定义会有如下的特性:

2.1 访问器方法(geter和seter):

1 访问器方法:get方法就是字段的名称set方法是set_后面加上字段的名称如:set方法:inline void set_email(const std::string& value);inline void set_email(const char* value);get方法:inline const ::std::string& email() const;2 has_方法: 用来判断是否为(可选或者必选)字段设置过值如:inline bool has_email() const;3 clear_方法: 清除字段值,使之成为空状态如:inline void clear_email();4 字符串:多了mutable_方法,可以取得字段值的间接指针;还多了一个set_方法,是用char指针作为参数。5 repeated字段,会有如下的方法:A _size方法:判断有多少个元素如:inline int phone_size() const;B 没有has_方法C 通过索引取得或者更新元素如:inline const ::tutorial::Person_PhoneNumber& phone(int index) const;D add_方法:加入新的元素如:inline ::tutorial::Person_PhoneNumber* add_phone();

2.2 枚举和嵌套类型

生成的代码含有枚举类型Person::PhoneType,其值可以是Person::MOBILE、Person::HOME、Person::WORK生成的代码含有嵌套类Person::PhoneNumber,但是实际的名称是Person_PhoneNumber,如果需要前向声明,则需要使用名字Person_PhoneNumber。

2.3 标准消息方法

bool IsInitialized() const:是否所有必需的字段都已经设置string DebugString() const:返回表示消息的人类可读的字符串,对于调试特别有用void CopyFrom(const Person& from):复制 void Clear():清除所有字段

2.4 解析和序列化

A bool SerializeToString(string* output) const;序列化message,存储到string中。注意其中的字节是二进制的,而不是文本。也就是说序列化之后,如写入文件等,你仍然看不懂,因为是二进制的。B bool ParseFromString(const string& data);从字符串中解析出message,这就是反序列化。C bool SerializeToOstream(ostream* output) const;将消息写入到C++ ostream中。D bool ParseFromIstream(istream* input);从C++ istream中解析出消息。以上也就是说,protocol buffer总共有那么两种类型的交互方式:一种就是直接跟string进行交互;还有一种就是跟istrem或者ostream进行交互。

3 可扩展性设计原则

应用发布之后,将来很可能需要改进protocol buffer定义。为保证新的格式向后兼容,旧的格式向前兼容,对于新版本的定义:· 不得修改任何已有字段的序号· 不得增加或者删除required字段· 可以删除optional或者repeated字段· 可以添加新的optional或者repeated字段,但是必须使用新的序号   只要遵循上述规则,则旧的程序可以很好地处理新的消息(简单地忽略新的字段)。· 对于旧的程序:被删除的optional字段具有默认值;被删除的repeated字段是空的。新的程序也可以透明地处理旧的消息。· 但是:新的optional字段不会出现在旧的消息中,所以(新的程序)要么显式地调用has_方法进行检查,要么在.proto文件中字段序号后面用[default=value]定义默认值。· 而且:新的repeated字段不会出现在旧的消息中,(新的程序)没法判断是(新的程序)把它设置成空了,还是(旧的程序)根本就没有设置这个字段,因为没有has_方法!

 

转载于:https://my.oschina.net/u/1024767/blog/857136

你可能感兴趣的文章
我的友情链接
查看>>
.Net Core IFormFile 始终为空的问题
查看>>
图片自适应
查看>>
【opengl】绘制一个立方体并在表面添加文字(添加文理)
查看>>
Distributed vSwitch分布式交换机
查看>>
用java实现短信发送的实例分享
查看>>
《构建之法》阅读笔记及项目管理软件
查看>>
VC中动态分配的几种写法
查看>>
excel数据比对,查找差异
查看>>
python3 简单登录,注册测试代码
查看>>
MAC VMWare Fusion配置mac和win7虚拟机互相访问
查看>>
awk正则匹配和awk命令统计某程序的CPU总的利用率
查看>>
CentOS7安装grafana
查看>>
bzoj 1823: [JSOI2010]满汉全席
查看>>
实战部署openldap主从架构
查看>>
我的技术路还很长
查看>>
第二阶段团队进展报告(4)
查看>>
Nginx:强劲的Web引擎
查看>>
vector容器与find算法
查看>>
Socket粘包问题
查看>>