protobuf用法(C++)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

文章目录

一、protobuf简介

二、使用步骤

1.创建.proto文件

protoc3语法

2.编译proto文件

3.使用序列化和反序列化


一、protobuf简介

        protobuf(protocal buffer)是一种序列化数据结构的方法。其特点有:

        1.支持多种语言(本文使用的是C++),多个平台。

        2.类比于XML更小、更快、更简单。

        3.扩展性、兼容性好。可以更新数据结构,而不破坏原有的结构和程序。

二、使用步骤

        1. 编写 .proto ⽂件,⽬的是为了定义结构对象(message)及属性内容。
        2. 使⽤ protoc 编译器编译 .proto ⽂件,⽣成⼀系列接⼝代码,存放在新⽣成头⽂件和源⽂件中。
        3. 依赖⽣成的接⼝,将编译⽣成的头⽂件包含进我们的代码中,实现对 .proto ⽂件中定义的字段进⾏设置和获取,和对 message 对象进⾏序列化和反序列化。

1.创建.proto文件

        文件命名应为全小写字母,多个词之间使用'_'间隔。

        文件内容使用两个空格为缩进。

protoc3语法

        指定proto3语法,和创建命名空间。

syntax = "proto3";
package namespace;

        定义消息,消息类型名使用驼峰命名法,首字母大写。

message 消息类型名{
}

        定义消息字段,字段定义格式为:字段类型 字段名 = 字段唯⼀编号。字段编号范围是1 ~ 536,870,911 (2^29 - 1),其中 19000 ~ 19999 不可⽤。

          范围为 1 ~ 15 的字段编号需要⼀个字节进行编码, 16 ~ 2047 内的数字需要两个字节 进行编码。编码后的字节不仅只包含了编号,还包含了字段类型。所以 1 ~ 15 要⽤来标记出现常频 繁的字段,要为将来有可能添加的、频繁出现的字段预留⼀些出来。
message People{
    string name = 1;
    int age = 2;
}

2.编译proto文件

protoc [--proto_path=IMPORT_PATH] --cpp_out=OUT_DIR path/to/file.proto
protoc 是Protocol Buffer 提供的命令⾏编译⼯具。
--proto_path 指定被编译的.proto⽂件所在⽬录,可多次指定。可简写成 -I IMPORT_PATH 。如不指定该参数,则在当前⽬录进⾏搜索。当某个.proto ⽂件 import 其他 .proto ⽂件时,或需要编译的 .proto ⽂件不在当前⽬录下,这时就要⽤-I来指定搜索⽬录。
--cpp_out= 指编译后的⽂件指定为C++文件。
OUT_DIR 编译后⽣成⽂件的⽬标路径。
path/to/file.proto 要编译的.proto⽂件。

        对于编译⽣成的 C++ 代码,包含了以下内容 :

        对于每个 message ,都会⽣成⼀个对应的消息类。 在消息类中,编译器为每个字段提供了获取和设置⽅法,以及⼀下其他能够操作字段的⽅法。 编辑器会针对于每个 .proto ⽂件⽣成 .h .cc ⽂件,分别用来存放类的声明与类的实现。

        在消息类的⽗类 MessageLite 中,提供了读写消息实例的⽅法,包括序列化⽅法和反序列化⽅法

class MessageLite {
public:
 //序列化:
 bool SerializeToOstream(ostream* output) const; // 将序列化后数据写⼊⽂件
流
 bool SerializeToArray(void *data, int size) const;
 bool SerializeToString(string* output) const;
 
 //反序列化:
 bool ParseFromIstream(istream* input); // 从流中读取数据,再进⾏反序列化动作
 bool ParseFromArray(const void* data, int size);
 bool ParseFromString(const string& data);
};

3.使用序列化和反序列化

#include <iostream> 
#include "contacts.pb.h" // 引⼊编译⽣成的头⽂件
using namespace std; 
 
int main() 
{ 
     string people_str; 
     contacts::PeopleInfo people; 
     people.set_age(20); 
     people.set_name("张三"); 
     // 调⽤序列化⽅法,将序列化后的⼆进制序列存⼊string中
     if (!people.SerializeToString(&people_str))
         cout << "序列化联系⼈失败." << endl; 
     contacts::PeopleInfo people; 
     // 调⽤反序列化⽅法,读取string中存放的⼆进制序列,并反序列化出对象
     if (!people.ParseFromString(people_str))
         cout << "反序列化出联系⼈失败." << endl; 
 }
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值