protocol buffer 簡稱 protobuf,是用於結構化資料序列化的靈活、高效、自動的方法,又如 xml,不過它更小、更快、也更簡單。你可以定義自己的資料結構,然後使用**生成器生成的**來讀寫這個資料結構。你甚至可以在無需重新部署程式的情況下更新資料結構。
本文主要介紹 protobuf 裡的反射功能,使用的pb版本為2.6.1,同時為了簡潔,對 repeated/extension 欄位的處理方法沒有說明。
最初是起源於這樣乙個問題:
給定乙個pb物件,如何自動遍歷該物件的所有字段?
即是否有乙個通用的方法可以遍歷任意pb物件的所有字段,而不用關心具體物件型別。
使用場景上有很多:
比如json格式字串的相互轉換,或者bigtable裡根據pb物件的字段自動寫列名和對應的value。
例如定義了pb messge型別person如下:
person person;能否將該物件自動轉化為json字串,或者自動的寫hbase裡的多列:person.set_name("yingshin");
person.set_age(21);
如果設定了新的字段,比如person.set_email("[email protected]"),則自動新增新的一列:
答案就是pb的反射功能。
我們的目標是提供這樣兩個介面:
//從給定的message物件序列化為固定格式的字串void serialize_message(const google::protobuf::message& message, std::string* serialized_string);
//從給定的字串按照固定格式還原為原message物件
各個類以及介面說明:
1.1 message
person是自定義的pb型別,繼承自message. messagelite作為message基類,更加輕量級一些。
通過message的兩個介面getdescriptor/getreflection,可以獲取該型別對應的descriptor/reflection。
1.2 descriptor
descriptor是對message型別定義的描述,包括message的名字、所有欄位的描述、原始的proto檔案內容等。
獲取所有欄位的個數:int field_count() const
獲取單個字段描述型別fielddescriptor的介面有很多個,例如
const fielddescriptor* field(int index) const;//根據定義順序索引獲取1.3 fielddescriptorconst fielddescriptor* findfieldbynumber(int number) const;//根據tag值獲取
const fielddescriptor* findfieldbyname(const string& name) const;//根據field name獲取
fielddescriptor描述message中的單個字段,例如欄位名,字段屬性(optional/required/repeated)等。
對於proto定義裡的每種型別,都有一種對應的c++型別,例如:
enum cpptype else {field = iter->second;
assert(!field->is_repeated());
switch (field->cpp_type()) {
#define case_field_type(cpptype, method, valuetype)
case google::protobuf::fielddescriptor::cpptype_##cpptype: {
reflection->set##method(
message,
field,
*(reinterpret_cast(value.c_str())));
std::cout name() (value.c_str())) enum_type()->findvaluebynumber(*(reinterpret_cast(value.c_str())));
reflection->setenum(message, field, enum_value_descriptor);
std::cout name() (value.c_str())) setstring(message, field, value);
std::cout name() mutablemessage(message, field);
parse_message(value, submessage);
break;
default: {
break;
protobuf反射機制
參考 google protocol buffers protobuf 是一款非常優秀的庫,它定義了一種緊湊的可擴充套件二進位制訊息格式,特別適合網路資料傳輸。它為多種語言提供 binding,大大方便了分布式程式的開發,讓系統不再侷限於用某一種語言來編寫。在網路程式設計中使用 protobuf 需...
Protobuf反射功能
include include include include include person.pb.h using namespace std string package typedef void callbackfunc const string type name,google protobu...
Protobuf協議格式詳解
protobuf 是google開源的乙個序列化框架,類似xml,json,最大的特點是基於二進位制,比傳統的xml表示同樣一段內容要短小得多。還可以定義一些可選字段,用於服務端與客戶端通訊。前面幾篇文章說了protobuf的用法,看到網上也沒有分析protobuf協議的文章,就利用一些時間寫了 p...