protobuf

Compile and install

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

use

In fact, the usage is very simple (no issues such as tcp packets are involved for the time being):

1 Syntax of proto file

The main templates are as follows:

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;
}

The above proto file uses the protoc command to generate a .h file and a .cc file. These two files are the definitions of the generated classes.

Notice:

required specifies that the field must be provided, otherwise the message is not initialized.

optional fields can be set or not. Default values ​​are used when fields are not set, and default values ​​for optional fields can be specified.

     If no default value is specified, 0 is the default value for numeric types;

     For strings, the empty string is the default;

     For bool type, false is the default value;

     For embedded message types, the default value is the default instance or metatype of this message, where each field is not set.

     For optional or required fields with no explicit set value, calling the accessor always returns the field's default value.

repeated defines that the field can be repeated multiple times (including 0). The order of each repeated value is preserved, and the repeating field can be thought of as a dynamic array.

 

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

2 Definition and interface details of the generated classes

The generated class definition of each message will have the following characteristics:

2.1 Accessor methods (geter and 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 Enumerations and Nested Types

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

2.3 Standard message methods

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

2.4 Parsing and Serialization

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 Design principles for scalability

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

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325981066&siteId=291194637