protobuf編碼規則
protobuf c++相關程式設計
protobuf 是一種平台無關、語言無關,可擴充套件的序列化資料格式,相比較與json和xml,具有高效性和靈活性。
message被定義為乙個.proto檔案
// an highlighted block
syntax =
"proto2"
;package tutorial;
message person
message phonenumber
repeated phonenumber phones =4;
}message addressbook
首先,需要在宣告使用的是proto協議的版本,package會被編譯生成c++中的namespace;
譬如,package tutorial 會被編譯生成namespace tutorial{};
每個message 會被編譯生成每個類,譬如message person會被編譯生成class person;
由message定義知,每個message中均勻一些數字域,該數字域是唯一的;
不同的數字定義了mesage二進位制編碼格式的乙個域;
10000—19999是系統保留的數字,不能用來定義型別
required:該訊息域使用需要注意,如果在乙個proto檔案中將某個域定義為required,則其他使用者如果想改變該域,會導致錯誤;每個message必須定義乙個required
optional:如果optional域的變數為被設定,則message在被解析時,會議預設值代替;每個message可以定義或者不定義該域
repeated:該域能被重複0次或者多次,每次的值均會被儲存
// an highlighted block
syntax =
"proto2"
;package test_econd;
message test1
如上定義乙個message,利用protoc工具對其進行編譯
編譯命令為:
protoc -i=./pb --cpp_out=./pb ./pb/test.proto
-i 為包含proto的原始檔路徑,–cpp_out為編譯生成的.h和.cc 所在的檔案路徑, 後面跟所要編譯的proto檔案
// an highlighted block
0000
:08ac 020a
其序列化過程如下:
對於a=300;其數字域為1,因此1<<3,左移三位
其型別為int32, 因此用type=000表示
1<<3 | type =01000 = 08
300的二進位制表示為100101100
在protobuf編碼協議中,以整數的從低位開始數起,7位為一組,並增加乙個最高有效位msb,然後將組順序想調,最高有效位為1表示改數字位元組表示結束,為0表示這屬於乙個整數位元組表示的一部份;
對於300的10 0101100,調轉兩組變為 0101100 10,由於0101100變為300的最高位元組組,因此在其最高位加1變為1010 1100也即 ac,對於10,則補0變為00000010也即02,因此300編碼的結果為08ac 02
至於最後的0a, 則是換行符的ascii碼值,pb序列化會在位元組末尾加個換行符借用官網的例子,假設message定義如下
// an highlighted block
syntax =
"proto2"
;package test_econd;
message test2
則當將test2的b設定為testing時,其編碼過程如下:
字串的型別為type=2, 數字域為2,數字域<<3
然後將其結果 | type
用可變位元組表示字串的長度,即07
testing被編碼為utf8型別的 74 65 73 74 69 6e 67
proto檔案的實現,我編寫測試用例命名為test.proto
其實現如下:
// an highlighted block
syntax =
"proto2"
;package test_econd;
message test1
在相應的目錄下執行:
protoc -i = ./src --cpp_out == ./src ./src/test.proto
在src中生成test.pb.h和test.pb.cc檔案
建立write_pb.**件,如下
// an highlighted block
#ifndef qin_write_pb_h
#define qin_write_pb_h
#include
#include
#include "test.pb.h"
void
promptfortest
(test_econd:
:test1* test1)
;#endif
write_pb.cpp實現如下
// an highlighted block
////
//#include "write_pb.h"
void
promptfortest
(test_econd:
:test1* test1)
main函式實現為
// an highlighted block
////
//#include
#include
#include "base/base64.h"
#include "write_pb.h"
int main
(int argc, char* ar**)
test_econd:
:test1 test1_1;
promptfortest
(&test1_1)
;// base64編碼
std:
:cout <<
"序列化結果:"
<< output << std:
:endl;
}// 解析字串
google:
:protobuf:
:shutdownprotobuflibrary()
;return0;
}
驗證輸出結果為:
[1] [protobuffers] (
關於protobuf的一些總結
最近面試中被問protobuf的加解碼原理,非常的尷尬,因為我沒了解過,這裡稍作總結 proto檔案 每乙個proto檔案其實對應著我們正常的乙個模型 也就是model 只是proto檔案是用來描述這樣的乙個模型的檔案,並非實際上的工程model。舉個例子,檔案person.proto messag...
protobuf3的學習筆記
學習protobuf的過程中踩了不少的坑,這篇博文算是乙個小結吧!1 windows 10 2 visualstudio 2017 3 google.protobuf.tools.3.9.1 4 google.protobuf.3.9.1 這裡先構建乙個普通的.proto檔案,檔名為myreques...
protobuf反射機制
參考 google protocol buffers protobuf 是一款非常優秀的庫,它定義了一種緊湊的可擴充套件二進位制訊息格式,特別適合網路資料傳輸。它為多種語言提供 binding,大大方便了分布式程式的開發,讓系統不再侷限於用某一種語言來編寫。在網路程式設計中使用 protobuf 需...