c++使用proto文件方法简介

2023-11-07

GoogleProtocol Buffers 简称 Protobuf,是 Google 公司内部的混合语言数据标准.它提供一种轻量,高效的结构化数据存储结构.

简介

为什么要使用protobuf?

1.   官方文档中提到一些protobuf的优点, protobuf灵活高效的结构化数据存储格式.方便用于序列化, 适合做RPC的数据交换.

2.   相比 XML , protobuf 比 XML 更小、更快、更简单.仅需要写一个 *.proto 文件描述需要的数据结构, protobuf会帮助你实现相关类和方法(自动化多好!).

3.   目前提供 C++, Java, Python, Go, C#等多种语言 的API

 

安装

在ubuntu上一键安装

sudoapt-get install protobuf-compiler

 

定义proto文件

定义proto文件较为简单,给每个结构体数据定义一个message,然后给结构体中的每个数据添加一个类型和名称,例如,想要定义一个address.proto文件

package tutorial;
message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

message AddressBook {
  repeated Person person = 1;
}

有如你所见,消息格式很简单,每个消息类型拥有一个或多个特定的数字字段,每个字段拥有一个名字和一个值类型。值类型可以是数字(整数或浮点)、布尔型、字符串、原始字节或者其他ProtocolBuffer类型,还允许数据结构的分级。你可以指定可选字段,必选字段和重复字段。

一旦你定义了自己的报文格式(message),你就可以运行ProtocolBuffer编译器,将你的 .proto 文件编译成特定语言的类。这些类提供了简单的方法访问每个字段(像是 query()和 set_query() ),像是访问类的方法一样将结构串行化或反串行化。

编译proto文件

现在已经拥有了 .proto文件,下一步就是编译生成相关的访问类。运行编译器 protoc 编译你的 .proto文件。

1.   如果还没安装编译器则下载并按照README的安装。

2.   运行编译器,指定源目录和目标目录,定位你的 .proto文件到源目录,然后执行:

protoc-I=$SRC_DIR –cpp_out=$DST_DIRaddressbook.proto

此操作生成c++格式的proto文件,如果想生成Python、java等类型的,把cpp换成python、java等即可,该操作生成如下两个文件:

addressbook.pb.h    定义了c++的头文件

addressbook.pb.cc   包含了类的实现

 

protocol buffer API

编译后的name、id、emal、和phone有如下方法:

// name
  inline bool has_name() const;
  inline void clear_name();
  inline const ::std::string& name() const;
  inline void set_name(const ::std::string& value);
  inline void set_name(const char* value);
  inline ::std::string* mutable_name();

  // id
  inline bool has_id() const;
  inline void clear_id();
  inline int32_t id() const;
  inline void set_id(int32_t value);

  // email
  inline bool has_email() const;
  inline void clear_email();
  inline const ::std::string& email() const;
  inline void set_email(const ::std::string& value);
  inline void set_email(const char* value);
  inline ::std::string* mutable_email();

  // phone
  inline int phone_size() const;
  inline void clear_phone();
  inline const ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >& phone() const;
  inline ::google::protobuf::RepeatedPtrField< ::tutorial::Person_PhoneNumber >* mutable_phone();
  inline const ::tutorial::Person_PhoneNumber& phone(int index) const;
  inline ::tutorial::Person_PhoneNumber* mutable_phone(int index);
  inline ::tutorial::Person_PhoneNumber* add_phone();

如你所见,获取字段的方法都是字段名称的小写,如

inline const ::std::string& name()const;
inline int32_t id()const;
inline const ::std::string& email()const;
inline const ::tutorial::Person_PhoneNumber& phone(int index) const;

设置字段名称的方法都已set_开头,singular (required or optional) 类型的字段有has_开头的方法,如果该字段已经设置了,那么该方法返回true

最后,每个字段都有一个clear_方法来把字段复位为空状态

 

数字类型的字段id只有基本的设置字段的方法,string型的字段name和email有几个其他的方法,mutable_开头的方法让你得到一个直接指向string类型的指针,及时email未被设置,你也可以调用mutable_email(),它将会自动初始化为一个空的string。如果字段在调用这个方法之前没有被设置,那么返回的字符串将为空(而不是缺省值)。调用这个方法后,has_foo()返回 true,foo()返回被写入到字符串(foo)中的任何值。通过调用 Clear()或 clear_foo()清除此指针。

 

Repeated类型的字段有一些特殊的方法

_size:检查有多少个字段

使用index来获取特定的字段

更新一个已经存在的字段

add_方法添加一个新的字段

 

生成的代码包含一个PthonType枚举,可以通过Person::PthonType或者它们的值Person::MOBILE, Person::HOME,和Person::WORK来调用它们.

 

标准消息方法

每个消息还包括一些其他方法用来检查和操作整个消息

bool IsInitialized() const; //检查是否所有的requied类型的消息都被设置了
string DebugString() const;//返回消息的一个可读类型,debug时很有用
void CopyFrom(const Person& from);//用给定的值来覆盖消息
void Clear();//把所有元素置回空状态


解析和序列化

最终,protocol buffer类有使用二进制格式来读写消息的方法:

bool SerializeToString(string* output) const;//序列化消息并把字节存储在给定的string类型中,注意字节是二进制类型,而不是text类型,我们只是使用string类型作为一个转换容易
bool ParseFromString(const string& data);//从string中解析消息
bool SerializeToOstream(ostream* output)const;//把消息写入一个给定的c++ostream中
bool ParseFromIstream(istream* input);//从一个给定的c++ istream中解析消息





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++使用proto文件方法简介 的相关文章

随机推荐

  • SpringBoot 接入 ELK - 动态索引详解

    1 说明 1 docker环境需要java maven环境 检查这两个 java version mvn version 2 本次ELK是使用docker运行的 ELK极其耗内存 服务器内存在4G及以内的 不建议安转 2 Linux mav
  • 【场景生成与削减】基于蒙特卡洛法场景生成及启发式同步回带削减风电、光伏、负荷研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码实现 1 概述 相关知识 基于概率距离削减法 蒙特卡洛削减
  • 数组函数some()、every()用法

    这两个方法用的其实并不多 但遇到了还是记录一下 some every 是用于判断数组的 1 some 不创建新数组 不改变原数组 判断为true则马上return true 否则return false let arr 1 2 3 4 5
  • UE4中常用的C++关键字:override

    override 描述 override保留字表示当前函数重写了基类的虚函数 目的 1 在函数比较多的情况下可以提示读者某个函数重写了基类虚函数 表示这个虚函数是从基类继承 不是派生类自己定义的 2 强制编译器检查某个函数是否重写基类虚函数
  • LeetCode 547. 朋友圈数量--无向连通图

    解析 方法一 DFS 遍历所有人 对于每一个人 寻找他的好友 找到好友后再找这个好友的好友 这样深度优先遍历下去 设置一个visited记录是否已经遍历了这个人 因为如果m个人最多m个朋友圈 设置后visited后 相同的朋友圈会检测到vi
  • 记录一些遇见的bug——项目启动报错Parameter 1 of constructor in com.example.filter.SimpleGlobalFilter required a bea

    记录一些遇见的bug 项目启动报错Parameter 1 of constructor in com example filter SimpleGlobalFilter required a bean of type org springf
  • angular2.0最新版环境搭建与常见问题

    第一步 安装Node js npm 安装Node js的时候自动就安装了npm 第二部 安装npm 由于npm官网镜像访问太慢 我们使用淘宝的npm镜像 在node命令窗口 windows的cmd linux的终端 npm install
  • 八数码深度优先搜索_Part 05:深度与广度优先搜索

    这节课重点学习深度优先搜索算法 简称为 DFS 和广度优先搜索算法 简称为 BFS DFS 和 BFS 经常在算法面试题当中出现 在整个算法面试知识点中所占的比重非常大 应用最多的地方就是对图进行遍历 树也是图的一种 深度优先搜索 Dept
  • 转:【Python3网络爬虫开发实战】6.4-分析Ajax爬取今日头条街拍美图

    摘要 本节中 我们以今日头条为例来尝试通过分析Ajax请求来抓取网页数据的方法 这次要抓取的目标是今日头条的街拍美图 抓取完成之后 将每组图片分文件夹下载到本地并保存下来 1 准备工作 在本节开始之前 请确保已经安装好requests库 如
  • Android Studio 太卡解决方法

    第一种情况 C盘快要满了 自行解决 第二种 修改Java 虚拟机启动时的参数 用于限制最大堆内存 在Android Studio Help gt Edit Custom VM Option 打开 在这里加上 Xmx2g 或者 Xmx4g 如
  • 【机器人学】机器人开源项目KDL源码学习:(2)牛顿拉普森迭代法求机器人的数值解

    对于串联机器人来说 求逆解的难度要大于求正解 市面上的工业机器人一般是利用的是利用解析法求封闭解 机器人有封闭解是有条件的 Pieper法则 另一种求逆解的方法是利用迭代法求数值解 适用于不满足Pieper法则的构型 特别适用于运动学冗余的
  • K8s ❉ 报错cannot stat ‘/etc/kubernetes/admin.conf’

    现象 报错提示 cannot stat etc kubernetes admin conf No such file or directory 解决方式 从master节点拷贝过来 master节点执行 root master scp et
  • 相机标定精度研究

    张建贺实验设计 1 外参重复性精度测试 同内参 不同外参特征点 9选择4 组合 1 外参几乎没有什么重复性误差 只要4对都正确 则刚性匹配基本正确 解释 激光点云到相机 转换本身的刚性匹配 而相机坐标系到图像坐标系是非刚性匹配 不同内参 同
  • pytorch分布式卡住

    在一台 A100 的实验室用单机多卡的方式跑 MoCoGAN HD 时 发现其在跑到 main worker 打完这行的 log 之后就卡住不动 手动 Ctrl C Options G step 5 batchSize 4 beta1 0
  • 如何搭建一个大数据平台:从新项目到成熟阶段

    在业务增涨过程中 每个企业不知不觉积累积累了一些数据 无论数据是多是少 企业都希望让 数据说话 通过对数据的采集 存储 分析 计算最终提供对业务有价值信息 此时 大数据平台的搭建就是企业面临的问题 搭建大数据平台有哪些思路 怎么样的搭建路径
  • LSTM lstm时间序列预测 用电量预测 完整代码数据

    视频讲解 LSTM lstm用工业用电量预测 时间序列预测 完整代码数据 哔哩哔哩 bilibili 代码 导包 import pandas as pd import numpy as np import tqdm import datet
  • 算法(62)-荷兰国旗-快排(详解+代码)

    问题1 问题二 代码 l 左值下标 r 右值下标 q 区分值 int partition int arr int l int r int p int less l 1 lt 区的右边界 下标 初始值 int more r 1 gt 区的左边
  • Heartbeat+crm+pingd+Drbd+NFS组合小型的集群

    Heartbeat crm pingd Drbd NFS组合小型的集群 一 网络结构图 二 准备工作 系统 CentOS release 5 3 Final Linux HA1 2 6 18 128 el5 1 SMP Wed Jan 21
  • Vite快速上手

    认识 Vite Vite 法语意为 快速的 发音 vit 是一种新型前端构建工具 能够显著提升前端开发体验 由两部分组成 一个开发服务器 它基于原生ES模块提供了丰富的内建功能 HMR的速度非常快速 一套构建指令 它使用rollup打开我们
  • c++使用proto文件方法简介

    GoogleProtocol Buffers 简称 Protobuf 是 Google 公司内部的混合语言数据标准 它提供一种轻量 高效的结构化数据存储结构 简介 为什么要使用protobuf 1 官方文档中提到一些protobuf的优点