Google Protobuf开发指南
1.简介
l 它是开源项目:http://code.google.com/p/protobuf/
l 由google开发,并且在google内部使用
l Protobuf的作用和xml、json是一回事,但他是二进制格式,性能好、效率高。
l 代码生成机制
l 支持多种语言
l 向后兼容、向前兼容
l 缺点:可读性、灵活性
2.protobuf目录结构
下载最新的protobuf-2.5.0.zip
解压后:
其中“editor”包含vim和emacs的语法高亮配置文件,”examples”是一个例子,vsprojects文件夹是visual studio的项目文件,src中是c++的源文件。
3.使用步骤
1. 编译lib文件
2. 在项目中引入include和lib文件夹
3. 开始使用
4.AddressBook例子
http://blog.sina.com.cn/s/blog_56dee71a01015i13.html
5.protobuf在网络通信中应用
Protobuf在TCP中使用注意事项
我的测试程序使用的TCP,于是一个很自然的问题,报文的边界或者报文长度问题,在网上google了一圈之后发现这个确实是个问题,解决问题的方案也很直接,在报文前面加上一个字段表示整个报文的长度(包括加上的字段)。
bool SerializeToArray(void * data, int size) const
bool SerializeToString(string * output) const
当然还有一些其他变种,我不喜欢使用stl string,所以选用了SerializeToArray
可以使用一下API反序列化:
boolParseFromArray(const void * data, int size)
boolParseFromString(const string & data)
以上写着函数都定义在 google/protobuf/message_lite.h 中
不过这里有更好的解决方法:
来自陈硕的文章《一种自动反射消息类型的 Google Protobuf 网络传输方案》
http://www.cnblogs.com/Solstice/archive/2011/04/03/2004458.html
6.".proto"文件语法
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;
}
1. 字段类型:bool,int32,float,double,string
2. 支持消息嵌套
3. 支持enum
索引号要按顺序指定
字段前缀:
required:必须的
optional:可选的
repeated:可以重复的
protoc使用
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
代码使用说明:
在程序开头添加:
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
在程序结尾添加:
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
代码风格指导
https://developers.google.com/protocol-buffers/docs/style
1. 消息和字段名:大写字母开头的驼峰表示法表示消息名称,如:SongServerRequest。使用小写字母+下划线分隔表示字段名,如:song_name。
message SongServerRequest {
required string song_name = 1;
}
2. 枚举类型:大写字母开头的驼峰表示法表示枚举名称,使用大写字母+下划线表示值
enum Foo {
FIRST_VALUE = 1;
SECOND_VALUE = 2;
}
注:每个值末尾使用分号而不是逗号