谷歌protobuf(Protocol buffers)的使用
生活随笔
收集整理的這篇文章主要介紹了
谷歌protobuf(Protocol buffers)的使用
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
谷歌protobuf的使用
- 一、概述
- 二、安裝
- 三、protobuf中的限定符
- 四、protobuf支持的數(shù)據(jù)類型
- 五、編譯
- 1. 將proto文件編譯成 C++ 文件
- 2. 將編譯好的文件與代碼一起編譯執(zhí)行
- 六、應(yīng)用
- 1. proto 文件的編寫(文件后綴名:proto)
- 2. 基礎(chǔ)應(yīng)用
- 3. 嵌套應(yīng)用(即message內(nèi)嵌套message)
- 4. libevent 和 protobuf 協(xié)作
一、概述
二、安裝
# 如果在解壓或安裝時(shí)出現(xiàn)問題,執(zhí)行 apt-get install autoconf automake libtool curl make g++ unzip # 1. 從github上克隆protobuf git clone https://github.com/protocolbuffers/protobuf # 2. 解壓下載好的文件 unzip protobuf-master.zip # 3. 進(jìn)入 protobuf-master 目錄 cd protobuf-master/ # 4. 執(zhí)行如下命令 ./autogen.sh ./configure make make check make install ldconfig # 5. 在 shell 下輸入protoc ,如果出現(xiàn) Usage: protoc [OPTION] PROTO_FILES 則成功。三、protobuf中的限定符
| required | 必填字段 |
| optional | 可選字段 |
| repeated | 可重復(fù)字段 |
四、protobuf支持的數(shù)據(jù)類型
| float | float | 無 |
| double | double | 無 |
| int32 | __int32 | 使用變長(zhǎng)編碼,對(duì)于負(fù)值的效率很低,如果你的域有可能有負(fù)值,請(qǐng)使用sint64替代 |
| uint32 | unsigned __int32 | 使用變長(zhǎng)編碼 |
| int64 | __int64 | 使用變長(zhǎng)編碼 |
| uint64 | unsigned __int64 | 使用變長(zhǎng)編碼 |
| sint32 | __int32 | 使用變長(zhǎng)編碼,這些編碼在負(fù)值時(shí)比int32高效的多 |
| sint64 | __int64 | 使用變長(zhǎng)編碼,有符號(hào)的整型值。編碼時(shí)比通常的int64高效。 |
| fixed32 | unsigned __int32 | 總是4個(gè)字節(jié),如果數(shù)值總是比228大的話,這個(gè)類型會(huì)比uint32高效。 |
| fixed64 | unsigned __int64 | 總是8個(gè)字節(jié),如果數(shù)值總是比總是比256大的話,這個(gè)類型會(huì)比uint64高效。 |
| sfixed32 | __int32 | 總是4個(gè)字節(jié) |
| sfixed64 | __int64 | 總是8個(gè)字節(jié) |
| bool | bool | |
| string | std::string | 一個(gè)字符串必須是UTF-8編碼或者7-bit ASCII編碼的文本。 |
| bytes | std::string | 可能包含任意順序的字節(jié)數(shù)據(jù)。 |
| enum | enum | 枚舉類型。如果要將兩個(gè)枚舉變量的值設(shè)為相等,那么需要添加如下代碼,否則會(huì)報(bào)錯(cuò):option allow_alias = true; |
五、編譯
1. 將proto文件編譯成 C++ 文件
# SRC_DIR: proto文件(example.proto)所在目錄 # cpp_out(DST_DIR): 制定了生成代碼的路徑 # example.proto: 指proto文件名 protoc -I=$SRC_DIR --cpp_out=$DST_DIR example.proto# 示例: protoc -I=./ --cpp_out=./ example.proto # 說明:在當(dāng)前目錄中查找 example.proto 并將生成的文件放在當(dāng)前目錄下2. 將編譯好的文件與代碼一起編譯執(zhí)行
g++ -std=c++11 example.cc example.pb.cc -lprotobuf六、應(yīng)用
1. proto 文件的編寫(文件后綴名:proto)
syntax = "proto2";package example;// 使用手機(jī)號(hào)登錄獲取驗(yàn)證碼(請(qǐng)求端) message get_code_requset {required string mobile = 1; }// 使用手機(jī)號(hào)登錄獲取驗(yàn)證碼(響應(yīng)端) message get_code_response {required int32 code = 1; // 響應(yīng)代號(hào)required int32 icode = 2; // 驗(yàn)證碼optional string reason = 3; // 失敗原因 }// 使用手機(jī)號(hào)登錄(請(qǐng)求端) message login_request {required string mobile = 1; // 手機(jī)號(hào)碼required int32 icode = 2; // 驗(yàn)證碼 }// 使用手機(jī)號(hào)登錄(響應(yīng)端) message login_response {required int32 code = 1; // 響應(yīng)代號(hào)optional string reason = 2; // 失敗原因 }// 查詢登錄記錄(請(qǐng)求端) message login_record_request {required string mobile = 1; // 手機(jī)號(hào)碼 }// 查詢登錄記錄(響應(yīng)端) message login_record_response {required int32 code = 1; // 響應(yīng)代號(hào)optional string reason = 2; // 失敗原因message login_record {required int32 timestamp = 1; // 時(shí)間戳required string device_name = 2; // 設(shè)備名}repeated login_record records = 3; }// 將以上代碼編譯成 C++ 文件 // protoc -I=./ --cpp_out=./ example.proto2. 基礎(chǔ)應(yīng)用
#include <string> #include <iostream> #include "example.pb.h"int main(int argc, char *argv[]) {std::string data; // 存儲(chǔ)序列化之后的數(shù)據(jù)// 客戶端發(fā)送請(qǐng)求{example::get_code_requset getCodeRequest;getCodeRequest.set_mobile("19912341234");getCodeRequest.SerializeToString(&data);std::cout << "serial[" << data.length() << "]:" << data << std::endl;}// 服務(wù)器端解析數(shù)據(jù){example::get_code_requset parse;parse.ParseFromString(data);std::cout << "mobile: " << parse.mobile() << std::endl;}return 0; }/********************************************************************************************** 使用如下語句在shell下編譯:g++ -std=c++11 example.cc example.pb.cc -o example.exe -lprotobuf **********************************************************************************************/3. 嵌套應(yīng)用(即message內(nèi)嵌套message)
#include <time.h> #include <string> #include <iostream> #include "example.pb.h"int main(int argc, char *argv[]) {std::string data; // 存儲(chǔ)序列化之后的數(shù)據(jù)// 客戶端發(fā)送請(qǐng)求{example::login_record_response response;response.set_code(200);response.set_reason("OK");// 插入登錄數(shù)據(jù)time_t now = time(NULL);for (int i = 0; i < 5; ++i) {example::login_record_response_login_record* login = response.add_records();login->set_timestamp(now + i);login->set_device_name(std::string("phone-") + std::to_string(i));}std::cout << "record size: " << response.records_size() << std::endl;// 序列化response.SerializeToString(&data);}// 服務(wù)器端解析數(shù)據(jù){example::login_record_response response;response.ParseFromString(data);std::cout << "code: " << response.code()<< " reason:" << response.reason()<< " parse size : " << response.records_size() << std::endl;for (int i = 0; i < response.records_size(); ++i) {const example::login_record_response_login_record& login = response.records(i);std::cout << "timestamp: " << login.timestamp()<< " device_name: " << login.device_name() << std::endl;}}return 0; }/********************************************************************************************** 使用如下語句在shell下編譯:g++ -std=c++11 example.cc example.pb.cc -o example.exe -lprotobuf **********************************************************************************************/4. libevent 和 protobuf 協(xié)作
總結(jié)
以上是生活随笔為你收集整理的谷歌protobuf(Protocol buffers)的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于51单片机的LCD1602显示温湿度
- 下一篇: LCD工作原理及结构