分类:other| 发布时间:2014-05-11 22:10:42
Protocol Buffers是一个灵活的,高效的,用于序列化结构化数据的自动机制- 有点类似XML,但更小巧,快捷和简单。
到项目的主页下载源代码: protobuf
然后键入以下命令进行安装(Linux环境):
$cd protobuf
$./configure
$make
$sudo make install
在源代码的exmaples子目录下有一个使用Protocol Buffers的例子,通过键入以下命令 编译此例子:
$make
编译完成后会生成C++、Java和Python版本的例子,本文针对C++版本进行讲解。
编译完成后会在example目录下生成add_person_cpp和list_person_cpp,让我们来 运行下这两个例子:
$./add_person_cpp test.file
test.file: File not found. Creating a new file.
Enter person ID number: 1
Enter name: zhangsan
Enter email address (blank for none): zhangsan@gmail.com
Enter a phone number (or leave blank to finish): 110
Is this a mobile, home, or work phone? home
Enter a phone number (or leave blank to finish):
$./list_people_cpp test.file
Person ID: 1
Name: zhangsan
E-mail address: zhangsan@gmail.com
Home phone #: 110
毫无疑问,可以正确地进行读写。
在这个例子中有一个addressbook.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文件由一个package声明语句开始,在C++中表示这个文件的内容都放在 namespace tutorial下。
接下来你会看到message的定义,message的字段可以是基础类型也可以是其他的message, 其中基础类型有:bool, int32, float, double, 和string。当然你也可以定义一系列的 enum值。
后面的"=1"、"=2"表示在二进制编码的过程中用于给每个字段打标签的唯一值。1-15的值 会比其他值少需要1个字节,所以尽量将1-15分配给常用的字段。
每个字段都由以下关键字修饰:
关于.proto文件的详细格式请查看: Protocol Buffer Language Guide
在example目录下,可以使用以下命令编译.proto文件
protoc -I=./--cpp_out=./ ./addressbook.proto
这条命令会生成addressbook.pb.h和addressbook.pb.cc文件。
通过查看生成的头文件会发现生成了以下接口:
// name
inline bool has_name() const;
inline void clear_name();
inline const ::std::string& name() const;
inline void set_name(const ::std::string& value);
inline void set_name(const char* value);
inline ::std::string* mutable_name();
// id
inline bool has_id() const;
inline void clear_id();
inline int32_t id() const;
inline void set_id(int32_t value);
// email
inline bool has_email() const;
inline void clear_email();
inline const ::std::string& email() const;
inline void set_email(const ::std::string& value);
inline void set_email(const char* value);
inline ::std::string* mutable_email();
// phone
inline int phone_size() const;
inline void clear_phone();
inline const ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >& phone() const;
inline ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >* mutable_phone();
inline const ::tutorial::Person_PhoneNumber& phone(int index) const;
inline ::tutorial::Person_PhoneNumber* mutable_phone(int index);
inline ::tutorial::Person_PhoneNumber* add_phone();
可以看到生成的接口中,getter就是和字段名相同的函数,除此外还有has_,clear_,set_等函数, 而对于string类型的字段还会多出一个mutable_的函数。 而对于repeated修饰的字段在这之外还会有一些额外的函数,比如_size等。
由于所有的message类型都是从class Message继承下来的, 因此除了以上生成的接口外还继承了class Message的所有接口: complete API documentation for Message