protobuf中.proto文件語(yǔ)法

一 基本說(shuō)明

.proto文件使用基本說(shuō)明
結(jié)構(gòu)定義文件為.proto敬察,可以使用import包含另一個(gè).proto文件,注釋使用//

二 語(yǔ)法

1 字段限制

required: 必須賦值的字符
optional: 可有可無(wú)的字段蹂安,可以使用[default = xxx]配置默認(rèn)值
repeated: 可重復(fù)變長(zhǎng)字段锐帜,類(lèi)似數(shù)組

2 tag

每個(gè)字段都有獨(dú)一無(wú)二的tag
tag 1-15是字節(jié)編碼,16-2047使用2字節(jié)編碼缠黍,所以1-15給頻繁使用的字段

3 類(lèi)型

圖片.png

系統(tǒng)默認(rèn)值
string默認(rèn)為空字符串瓷式;
bool默認(rèn)為false语泽;
數(shù)值默認(rèn)為0;
enum默認(rèn)為第一個(gè)元素

4 解析與序列化

每個(gè)message都包含如下方法廊驼,用于解析和序列化惋砂,注意目標(biāo)是字節(jié)形式,非文本酝掩。
bool SerializeToString(string* output) const: 將message序列化成二進(jìn)制保存在output中眷柔,注意保存的是二進(jìn)制,不是文本镶苞;僅僅是string作為容器鞠评。
bool ParseFromString(const string& data): 從給定的二進(jìn)制數(shù)值中解析成message
bool SerializeToOstream(ostream* output) const: 序列化到ostream中
bool ParseFromIstream(istream* input): 從istream中解析出message

三 舉例介紹

1 建立.proto文件

建立.proto文件定義message,如下addressbook.proto

syntax = "proto2"; // 定義語(yǔ)法類(lèi)型煌贴,通常proto3好于proto2,proto2好于proto1

package tutorial; // 定義作用域

message Person {        // 生成類(lèi)class Person : public ::google::protobuf::Message 
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType { // 定義枚舉類(lèi)型怠肋,生成Person_PhoneType類(lèi)型
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber { // 生成Person_PhoneNumber類(lèi)
    required string number = 1;
    optional PhoneType type = 2 [default = HOME]; // 值必須是枚舉類(lèi)型中的一個(gè)
  }
  repeated PhoneNumber phones = 4;
}

message AddressBook {
  repeated Person people = 1;
}

2 生成源文件

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
其中protoc工具地址:protoc

1) message Person{}

會(huì)生成源碼如下:

class Person  : public ::google::protobuf::Message {
Person(); // 默認(rèn)構(gòu)造函數(shù)
~Person(); // 默認(rèn)析構(gòu)函數(shù)
Person(const Person& other); // 拷貝構(gòu)造函數(shù)
Person& operator=(const Person& other); // 賦值構(gòu)造函數(shù)
void Swap(Person* other); // 內(nèi)容交換
const UnknownFieldSet& unknown_fields() const; 
UnknownFieldSet* mutable_unknown_fields(); 
static const Descriptor* descriptor();
static const Foo& default_instance();
};

2) required string name

生成源碼如下:

bool has_name() const; // 返回true笙各,如果name被設(shè)置
void clear_name(); // 清除name杈抢,has_name會(huì)返回false
const ::std::string& name() const; // 返回name字符串
void set_name(const ::std::string& value); // 設(shè)置name字符串
::std::string* mutable_name(); // 可以修改的字符串仑性,has_name會(huì)返回true

3) required int32 id

生成源碼如下:

bool has_id() const; // 返回true,如果id被設(shè)置
int32 id() const; // 返回id數(shù)值
void set_id(int32 value); // 設(shè)置id數(shù)值
void clear_id(); // 清除id歼捐,has_id會(huì)返回false

4) message Person { message PhoneNumber }

生成類(lèi)Person_PhoneNumber晨汹,并在Person類(lèi)內(nèi)定義:

typedef Person_PhoneNumber PhoneNumber;

其他消息如果要使用PhoneNumber,使用方法如下:

message OtherPerson {
    optional Person.PhoneNumber number = 1;
}

3 定義prototxt文件

定義如下:

people{
   name : "Lucy"
   id : 120
   email : "lucy@163.com"
   phones{
       number : "13540737210"
       type : HOME
   }
}

4 代碼中解析prototxt文件

/*************************************************************************                                                                                             
    > File Name: main.cpp
    > Author: ma6174
    > Mail: ma6174@163.com 
    > Created Time: Wed 09 Jan 2019 11:04:56 PM CST
 ************************************************************************/
#include<iostream>
#include "tutorial.AddressBook.pb.h"
using namespace std;

int main() {
    tutorial::Person one;
    string filename = "one.prototxt";
    ReadProtoFromTextFileOrDie(filename, &one);
    return 0;
}

編譯命令:

g++ main.cpp *.cc -std=c++11 `pkg-config --cflags --libs protobuf`

這一步編譯報(bào)錯(cuò):

main.cpp:15:43: error: ‘ReadProtoFromTextFileOrDie’ was not declared in this scope
  ReadProtoFromTextFileOrDie(filename, &one);
                                           ^

需要進(jìn)一步學(xué)習(xí)...

參考

[1] 官方指南.Protocol Buffer Basics: C++
[2] 博客.序列化之protobuf

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铝穷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子呻疹,更是在濱河造成了極大的恐慌筹陵,老刑警劉巖镊尺,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庐氮,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)输涕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)莱坎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)寸士,“玉大人,你說(shuō)我怎么就攤上這事乃正∩舨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵名党,是天一觀的道長(zhǎng)划栓。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蒋歌,這世上最難降的妖魔是什么委煤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任碧绞,我火速辦了婚禮,結(jié)果婚禮上讥邻,老公的妹妹穿的比我還像新娘。我一直安慰自己系宜,他們只是感情好发魄,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著口柳,像睡著了一般有滑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辣卒,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天睛榄,我揣著相機(jī)與錄音,去河邊找鬼啡莉。 笑死旨剥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的魄咕。 我是一名探鬼主播蚌父,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼苟弛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了膏秫?” 一聲冷哼從身側(cè)響起缤削,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滚婉,沒(méi)想到半個(gè)月后吨拗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哨鸭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年像鸡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哈恰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛔钙,死狀恐怖荠医,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兼贡,我是刑警寧澤娃胆,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布遍希,位于F島的核電站,受9級(jí)特大地震影響里烦,放射性物質(zhì)發(fā)生泄漏凿蒜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一招驴、第九天 我趴在偏房一處隱蔽的房頂上張望篙程。 院中可真熱鬧,春花似錦别厘、人聲如沸虱饿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)氮发。三九已至,卻和暖如春冗懦,著一層夾襖步出監(jiān)牢的瞬間爽冕,已是汗流浹背披蕉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工颈畸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乌奇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓眯娱,卻偏偏與公主長(zhǎng)得像礁苗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子徙缴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353