一、简介
protocolbuffer(以下简称PB)是google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。作为一种效率和兼容性都很优秀的二进制数据传输格式,可以用于诸如网络传输、配置文件、数据存储等诸多领域。
二、版本下载
目前的最新版是protoc-2.5.0,各个版本的下载列表的网址:http://code.google.com/p/protobuf/downloads/list
linux版本是protoc-2.5.0.tar.gz; windows版本是protoc-2.5.0.zip
三、安装
下面以linux为例 :
安装:$ tar -xzvf protoc-2.5.0.tar.gz 会解压出protobuf-2.5.0目录
$ cdprotobuf-2.5.0
$ ./configure --prefix=/usr/local/protobuf-2.5.0
$ make
$ make check
$ su 切换到root用户
# make install
配置:查看编译生成的目录
$ cd /usr/local/protobuf-2.4.1
bin include lib
其中,bin中的protoc是.proto文件的处理器,可用这个工具生成cpp,java,python文件.
由于系统常用这个工具,可以将其ln或者直接拷贝到系统环境bin下
ln -s /usr/local/protobuf-2.4.1/bin/protoc /usr/bin/protoc
同样,可以将头文件ln或者直接拷贝到系统环境
ln -s /usr/local/protobuf-2.4.1/include/google /usr/include/google
将lib文件ln或者直接拷贝到系统环境
略,方法同上.
此时,protobuf的开发环境已经搭建了。
四 、proto buffer 的用法
- 数据结构体:
- message message_name{message_body;}
- message_body格式:
- 例如required int32 query = 1[defaut=10];
- 形式为:rule type name = value[other_rule];
- 规则:
- required表示必须具有该值域;
- optional表示可选的值域;
- repeated表示可重复的值域(即>=0);
- true];形式;
- value值:
- value值最小为1,是底层编码时使用其中1-15占一位,>15则会占多位;
- 不同的message中的value值互不干扰,常以1开始计数。
- 数据类型之基本类型:
- .proto Type C++ Type Java Type
- double double double
- float float float
- int32 int32 int
- int64 int64 long
- uint32 uint32 int
- uint64 uint64 long
- sint32 int32 int
- sint64 int64 long
- fixed32 uint32 int
- fixed64 uint64 long
- sfixed32 int32 int
- sfixed64 int64 long
- bool bool boolean
- string string String
- bytes string ByteString
- 数据类型之复杂类型:
- 复杂类型主要包括:枚举,其他message,groups等。
- enum Corpus{WEB=0;LOCAL=1}
- 枚举定义在message中。
- 可以使用其他message作为类型来定义成员。
- union结构。
- 嵌套定义:
- 可以嵌套定义message结构,而嵌套定义的message被其他message作为成员类型时需要形式为outmessage.inmessage形式。
- 包结构:
- 定义形式:package foo.bar;
- 对应C++中则生成两个命名空间foo和bar,且bar定义在foo中;
- "myproject/other_protos.proto";来引入.proto文件;
- 引用其他package中message时需要完整的package路径;
- Services:
- 主要用于RPC系统中,在.proto中定义接口;
- 定义形式如例子:
- service SearchService {
- return (SearchResponse);
- }
- .proto文件编译:
- 格式:
- protoc -–proto_path=(.proto文件路径) -–cpp_out=(.cc .java生成文件路径) (.proto文件路径)/?.proto
- -–proto_path 简化为: --I
- 其中可根据需要更改:cpp_out选项为java_out/python_out。
- 例子:
- protoc -I=./ --cpp_out=./ model.proto
五、简单实例
proto buf的后缀名是.proto
编写hello.proto,代码如下:
View Code 1 package hello;
message Hello{
required int32 id = 1; //user id
required string name = 2; //user name
optional string email = 3; //user email
}
接着,要用protoc生成一个对应的类,我把它生成在./out目录里:
$ protoc hello.proto --cpp_out=./out
接下来,在out目录下,会生成两个文件:
$ ls
hello.pb.cc hello.pb.h
接下来,编写测试用的c++代码,hello.cc,代码如下:
#include <stdio.h>
#include <string.h>
#include "out/hello.pb.h"
usingnamespace std;
usingnamespace hello;
int main()
{
Hello a;
a.set_id(0818);
a.set_name("liangzhijun");
string tmp;
bool ret = a.SerializeToString(&tmp);
if (ret)
{
printf("encode success!\n");
}else{
printf("encode faild!\n");
}
Hello b;
ret = b.ParseFromString(tmp);
if (ret)
{
printf("decode success!\n id= %d \n name = %s\n", b.id(), b.name().c_str());
}else{
printf("decode faild!\n");
}
return0;
}
接着,编译一下这个代码,由于使用了protobuf的库,所以编译的时候,要把这些库也链接进来:
g++ hello.cc ./out/hello.pb.cc -o hello -I./out -I/usr/local/protobuf/include -L/usr/local/lib -lprotobuf
这样,就生成了测试程序。
运行一下:
$ ./hello
encode success!
decode success!
id= 0818
name = liangzhijun
六、参考
1.