protobuf學習總結

2021-10-01 02:01:42 字數 3580 閱讀 9729

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 需...