谷歌protobuf(Protocol buffers)的使用
生活随笔
收集整理的这篇文章主要介绍了
谷歌protobuf(Protocol buffers)的使用
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
谷歌protobuf的使用
- 一、概述
- 二、安装
- 三、protobuf中的限定符
- 四、protobuf支持的数据类型
- 五、编译
- 1. 将proto文件编译成 C++ 文件
- 2. 将编译好的文件与代码一起编译执行
- 六、应用
- 1. proto 文件的编写(文件后缀名:proto)
- 2. 基础应用
- 3. 嵌套应用(即message内嵌套message)
- 4. libevent 和 protobuf 协作
一、概述
二、安装
# 如果在解压或安装时出现问题,执行 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. 进入 protobuf-master 目录 cd protobuf-master/ # 4. 执行如下命令 ./autogen.sh ./configure make make check make install ldconfig # 5. 在 shell 下输入protoc ,如果出现 Usage: protoc [OPTION] PROTO_FILES 则成功。三、protobuf中的限定符
| required | 必填字段 |
| optional | 可选字段 |
| repeated | 可重复字段 |
四、protobuf支持的数据类型
| float | float | 无 |
| double | double | 无 |
| int32 | __int32 | 使用变长编码,对于负值的效率很低,如果你的域有可能有负值,请使用sint64替代 |
| uint32 | unsigned __int32 | 使用变长编码 |
| int64 | __int64 | 使用变长编码 |
| uint64 | unsigned __int64 | 使用变长编码 |
| sint32 | __int32 | 使用变长编码,这些编码在负值时比int32高效的多 |
| sint64 | __int64 | 使用变长编码,有符号的整型值。编码时比通常的int64高效。 |
| fixed32 | unsigned __int32 | 总是4个字节,如果数值总是比228大的话,这个类型会比uint32高效。 |
| fixed64 | unsigned __int64 | 总是8个字节,如果数值总是比总是比256大的话,这个类型会比uint64高效。 |
| sfixed32 | __int32 | 总是4个字节 |
| sfixed64 | __int64 | 总是8个字节 |
| bool | bool | |
| string | std::string | 一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。 |
| bytes | std::string | 可能包含任意顺序的字节数据。 |
| enum | enum | 枚举类型。如果要将两个枚举变量的值设为相等,那么需要添加如下代码,否则会报错: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 # 说明:在当前目录中查找 example.proto 并将生成的文件放在当前目录下2. 将编译好的文件与代码一起编译执行
g++ -std=c++11 example.cc example.pb.cc -lprotobuf六、应用
1. proto 文件的编写(文件后缀名:proto)
syntax = "proto2";package example;// 使用手机号登录获取验证码(请求端) message get_code_requset {required string mobile = 1; }// 使用手机号登录获取验证码(响应端) message get_code_response {required int32 code = 1; // 响应代号required int32 icode = 2; // 验证码optional string reason = 3; // 失败原因 }// 使用手机号登录(请求端) message login_request {required string mobile = 1; // 手机号码required int32 icode = 2; // 验证码 }// 使用手机号登录(响应端) message login_response {required int32 code = 1; // 响应代号optional string reason = 2; // 失败原因 }// 查询登录记录(请求端) message login_record_request {required string mobile = 1; // 手机号码 }// 查询登录记录(响应端) message login_record_response {required int32 code = 1; // 响应代号optional string reason = 2; // 失败原因message login_record {required int32 timestamp = 1; // 时间戳required string device_name = 2; // 设备名}repeated login_record records = 3; }// 将以上代码编译成 C++ 文件 // protoc -I=./ --cpp_out=./ example.proto2. 基础应用
#include <string> #include <iostream> #include "example.pb.h"int main(int argc, char *argv[]) {std::string data; // 存储序列化之后的数据// 客户端发送请求{example::get_code_requset getCodeRequest;getCodeRequest.set_mobile("19912341234");getCodeRequest.SerializeToString(&data);std::cout << "serial[" << data.length() << "]:" << data << std::endl;}// 服务器端解析数据{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. 嵌套应用(即message内嵌套message)
#include <time.h> #include <string> #include <iostream> #include "example.pb.h"int main(int argc, char *argv[]) {std::string data; // 存储序列化之后的数据// 客户端发送请求{example::login_record_response response;response.set_code(200);response.set_reason("OK");// 插入登录数据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);}// 服务器端解析数据{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 协作
总结
以上是生活随笔为你收集整理的谷歌protobuf(Protocol buffers)的使用的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 基于51单片机的LCD1602显示温湿度
- 下一篇: LCD工作原理及结构