1、在.proto文件中定義消息格式
2、使用protobuf編譯器
3、使用c++ api來讀寫消息
0、為何使用protobuf?
1、原始內存數據結構,可以以二進制方式sent/saved.這種方式需要相同的內存布局和字節序。
2、以ad-hoc方式將數據項編碼成一個簡單字符串----比如,將4個int類型編碼成"12:3:-23:67"。這種方式簡靈活。適用於簡單數據。
3、將數據序列化為XML。這種方式很流行,因為xml可讀性好,編碼解碼方便,性能也好。僅僅XML dom樹比較復雜。
protobuf可以很好的解決上述問題。你編寫一個.proto文件來描述數據結構。protobuf編譯器使用它創建一個類,使用二進制方式自動編碼/解碼該數據結構。生成的類提供getter/setter方法。
最重要的是,protobuf支持在此基礎上進行格式擴展。
1、定義協議格式
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; }
該結構與c++或java很像.
.proto文件以包聲明開始,防止名字沖突。
簡單類型:bool, int32, float, double, string.
其它類型:如上述的Person, PhoneNumber
類型可以嵌套。
“=1”, “=2”標識唯一“tag”.tag數1-15需要至少一個字節。
required: 必須設置它的值
optional: 可以設置,也可以不設置它的值
repeated: 可以認為是動態分配的數組
google工程師認為使用required威害更大, 他們更喜歡使用optional, repeated.
2、編譯你的協議
運行protoc 來生成c++文件:
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
生成的文件為:
addressbook.pb.h,
addressbook.pb.cc
3、protobuf API
生成的文件中有如下方法:
// 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