ProtoBuf快速上手

news2024/12/23 18:40:13

文章目录

    • 创建 .proto文件
    • 编译 .proto文件
    • 编译后生成的文件
    • 序列化与反序列化的使用

此篇文章实现内容:

  • 对一个通讯录的联系人信息,使用PB进行序列化,并将结果输出
  • 对序列化的内容使用PB进行反序列化,解析联系人信息并输出
  • 联系人信息包含:姓名、年龄

创建 .proto文件

  • 建议文件名采用小写
  • 后缀名为.proto

image-20241002100409918

messgae可以定义属性字段,格式为:字段类型 字段名 = 字段唯一编号

  • 命名规范:全小写,多个字母之间用_连接
  • 字段类型分为标量数据类型和特殊类型
  • 字段唯一编号:用来标识字段,一旦开始使用就不能改变
.proto TypeNotesC++ Type
doubledouble
floatfloat
int32使用变长编码[1]。负数的编码效率较低⸺若字段可能为负值,应使用 sint32 代替int32
int64使用变长编码[1]。负数的编码效率较低⸺若字段可能为负值,应使用 sint64 代替int64
uint32使用变长编码[1]uint32
uint64使用变长编码[1]uint64
sint32使用变长编码[1]。符号整型。负值的编码效率⾼于常规的 int32 类型int32
sint64使用变长编码[1]。符号整型。负值的编码效率⾼于常规的 int64 类型int64
fixed32定长 4 字节。若值常大于2^28 则会比 uint32 更高效uint32
fixed64定长 8 字节。若值常大于2^56 则会比 uint64 更高效uint64
sfixed32定长4字节int32
sfixed64定长8字节int64
boolbool
string包含 UTF-8 和 ASCII 编码的字符串,长度不能超过2^32string
bytes可以包含任意的字节序列,长度不超过2^32string

[1]边长编码指的是:结果protobuf编码后,原本4字节或8字节的数可能会变为其他字节数

//语法指定行
syntax = "proto3";
//定义声明空间
package contacts;

//定义联系人message
message PeopleInfo
{
    //标识字段编号
    string name = 1;
    int32 age = 2;
}

这里字段唯一编号范围:[1 ~ 536, 870, 911(2^29-1)]

其中19000 ~ 19999不可用,因为protobuf协议实现中,对这些数进行了预留

1 ~ 15字段编号需要一个字节进行编码
6 ~ 2047需要两个字节进行编码。

编码之后的字节不仅仅包含编号,还包含字段类型,所以1 ~ 15要用来标记频繁出现的字段

可以按照protobuf插件,代码会有高亮显示

image-20241002095952976

编译 .proto文件

protoc --cpp_out=. contacts.proto
  • --cpp_out=.表明编译的proto文件会生成C++的代码,=.表明生成的C++文件在当前目录下
  • contacts.proto表明所依赖的文件

image-20241002100736478

如果不在这个目录下还想对contacts.proto进行编译:

protoc -I protobuf_10_2/ --cpp_out=protobuf_10_2/ contacts.proto
  • -I protobuf_10_2表示指定的搜索目录

image-20241002101122367

编译后生成的文件

编译之后生成了*.h*.cc文件,分别存放类的声明和类的实现

*.h文件为例:

这里就是生成的getset方法

image-20241002101436155

序列反序列方法:

image-20241002102328761

  • 在序列反序列化方法,都是继承messagemessage继承MessageLite,里面提供了序列反序列化的方法
  • 序列化之后的结果为二进制字节序列
  • 序列化的API都是const成员函数,因为序列化不会改变类对象的内容,而是将序列化的结果保存到函数入参指定地址当中

序列化与反序列化的使用

编写测试文件main.cc

  • 对联系人信息使用PB进行序列化,将结果输出
  • 对序列化内容使用PB进行反序列化,解析联系人信息并输入
#include<iostream>
#include<string>
#include<fstream>
#include"contacts.pb.h"
int main()
{
    std::string people_str;
    //序列化
    {
        contacts::PeopleInfo people;
        people.set_name("张三");
        people.set_age(20);
        if(!people.SerializeToString(&people_str))
        {
            std::cerr << "serialize error" << std::endl;
            return -1;
        }
        std::cout << "serialize success: " << people_str << std::endl;
    }

    //反序列化
    {
        contacts::PeopleInfo people;
        if(!people.ParseFromString(people_str))
        {
            std::cerr << "parse error" << std::endl;
        }
        std::cout << "parse success: " << std::endl;
        std::cout << "name: " << people.name() << std::endl; 
        std::cout << "age: " << people.age() << std::endl; 
    }
    return 0;
}

编译main.cc

g++ -o testPb main.cc contacts.pb.cc -std=c++11 -lprotobuf

也可以使用makefile:

testPb:main.cc contacts.pb.cc
	g++ -o $@ $^ -std=c++11 -lprotobuf
.PHONY:clean
clean:
	rm testPb

image-20241002111307892

相对于jsonxml来说,protobuf编码成了二进制,破解成本较大,所以protobuf编码是较安全的。

ProtoBuf需要依赖通过编译生成的头文件和源文件使用,所以开发人员就无需编写解析协议的代码,大大提高了开发效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2185402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【成神之路】Ambari实战-015-代码生命周期-metainfo-category详解

1.Redis 集群 metainfo.xml 示例 <?xml version"1.0"?> <metainfo><schemaVersion>2.0</schemaVersion><services><service><!-- Redis 集群服务的基本信息 --><name>REDIS</name><displayName>Redi…

MongoDB的安装与增删改查基本操作

MongoDB是一种非关系型数据库&#xff0c;是NoSQL语言&#xff0c;但是又是最接近关系型数据库的。内部存储不是表结构&#xff0c;但是可以对数据进行表结构的操作。 一、安装 在官网&#xff1a;Download MongoDB Community Server | MongoDB下载系统对应的版本进行安装即可…

html+css+js实现Collapse 折叠面板

实现效果&#xff1a; HTML部分 <div class"collapse"><ul><li><div class"header"><h4>一致性 Consistency</h4><span class"iconfont icon-jiantou"></span></div><div class"…

UFS 3.1架构简介

整个UFS协议栈可以分为三层:应用层(UFS Application Layer(UAP)),传输层(UFS Transport Layer(UTP)),链路层(UIC InterConnect Layer(UIC))。应用层发出SCSI命令(UFS没有自己的命令使用的是简化的SCSI命令),在传输层将SCSI分装为UPIU,再经过链路层将命令发送给Devices。下…

通信工程学习:什么是TCP传输控制协议

TCP&#xff1a;传输控制协议 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是因特网协议套件中最重要的协议之一&#xff0c;它为应用程序提供了可靠、面向连接的通信服务。以下是TCP协议的详细解释&#xff1a; 一、TCP传输控制协议的…

双十一有哪些值得入手的好物?这五款宝藏好物不容错过!

在这个金秋送爽、收获满满的季节里&#xff0c;我们迎来了万众瞩目的双十一购物狂欢节。这不仅仅是一场简单的消费盛宴&#xff0c;更是每一位消费者期待已久、精心筹备的年度购物盛典。随着电商平台的不断革新与优惠力度的持续加码&#xff0c;双十一已经从一个简单的促销日成…

使用百度文心智能体创建多风格表情包设计助手

文章目录 一、智能定制&#xff0c;个性飞扬二、多元风格&#xff0c;创意无限 百度文心智能体平台为你开启。百度文心智能体平台&#xff0c;创建属于自己的智能体应用。百度文心智能体平台是百度旗下的智能AI平台&#xff0c;集成了先进的自然语言处理技术和人工智能技术&…

单目3d重建DUSt3R 笔记

目录 DUSt3R 三维重建 报错RecursionError: maximum recursion depth exceeded in comparison 报错 numpy.core.multiarray failed to import 报错Numpy is not available 解决 升级版mast3r 速度变慢 修改了参数设置脚本&#xff1a; 测试效果 操作技巧 DUSt3R 三维重…

[已解决] Install PyTorch 报错 —— OpenOccupancy 配环境

目录 关于 常见的初始化报错 环境推荐 torch, torchvision & torchaudio cudatoolkit 本地pip安装方法 关于 OpenOccupancy: 语义占用感知对于自动驾驶至关重要&#xff0c;因为自动驾驶汽车需要对3D城市结构进行细粒度感知。然而&#xff0c;现有的相关基准在城市场…

torchvision.transforms.Resize()的用法

今天我在使用torchvision.transforms.Resize()的时候发现&#xff0c;一般Resize中放的是size或者是(size,size)这样的二元数。 这两个里面&#xff0c;torchvision.transforms.Resize((size,size))&#xff0c;大家都很清楚&#xff0c;会将图像的h和w大小都变成size。 但是…

【python实操】python小程序之过七游戏以及单词单复数分类

引言 python小程序之过7游戏、单词单复数分类 文章目录 引言一、过7游戏1.1 题目1.2 代码1.2.1 while循环1.2.2 for循环1.2.3 调用函数形式 1.3 代码解释 二、单词单复数分类2.1 题目2.2 代码2.3 代码解释 三、思考3.1 过七游戏3.2 单词单复数分类 一、过7游戏 1.1 题目 7的倍…

大模型 LLaMA-Omni 低延迟高质量语音交互,开源!

最近这一两周看到不少互联网公司都已经开始秋招发放Offer。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球…

python-patterns:Python 设计模式大全

python-patterns 是一个开源的 Python 项目&#xff0c;它提供了各种经典的设计模式的 Python 实现。设计模式是一种针对常见软件设计问题的可复用解决方案&#xff0c;通过使用设计模式&#xff0c;开发者可以编写出结构更加合理、易于维护和扩展的代码。 Python 是一门动态语…

GraphEval: A Knowledge-Graph Based LLM Hallucination Evaluation Framework

文章目录 题目摘要引言问题陈述相关工作GraphEval:我们的评估方法使用LLM构建知识GraphCorrect:使用GraphEval纠正幻觉实验讨论结论 题目 GraphEval:一个基于知识图的LLM幻觉评估框架 论文地址&#xff1a;https://arxiv.org/abs/2407.10793 摘要 评估大型语言模型(LLM)响应和…

【计算机科研方法指南】- 读书笔记《学术咸鱼自救指南》+于老师科研课

前言简介 因为自己在做计算机科研的时候&#xff0c;一开始很不顺利&#xff0c;所以专门去研究了一些具体的计算机科研方法。这里的方法主要参考了两个资料&#xff0c;一个是《学术“咸鱼”自救指南》&#xff0c;一个是于静老师科研课。 《学术“咸鱼”自救指南》是作者钱…

【微服务】组件、基础工程构建(day2)

组件 服务注册和发现 微服务模块中&#xff0c;一般是以集群的方式进行部署的&#xff0c;如果我们调用的时候以硬编码的方式&#xff0c;那么当服务出现问题、服务扩缩容等就需要对代码进行修改&#xff0c;这是非常不好的。所以微服务模块中就出现了服务注册和发现组件&…

视频创作黑科技!CogVideoX秒生成艺术视频

视频创作黑科技&#xff01;CogVideoX秒生成艺术视频 CogVideoX上线啦&#xff01;&#x1f389; 它能把文字和图片变成惊艳视频&#x1f3a5;。CogVideoX-5B如同好莱坞导演&#xff0c;快速生成高质量内容⚡&#xff0c;完美捕捉创意细节✨。让你轻松成为视频创作大师&#x…

Linux命令--03----帮助类命令、开关机类命令

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.帮助类命令man获取帮助信息help获得shell内置命令的帮助信息 2.开关机类命令2.1 开关机命令一般Linux不会经常进行关机操作,正确的关机流程为: sync>shutdown&…

初识TCP/IP协议

回顾上文 来回顾一下TCP协议的特性&#xff0c;有一道比较经典的题&#xff1a;如何使用UDP实现可靠传输&#xff0c;通过应用程序的代码&#xff0c;完成可靠传输的过程&#xff1f; 原则&#xff0c;TCO有啥就吹啥&#xff0c;引入滑动窗口&#xff0c;引入流量控制&#x…

电子连接器温升仿真教程 二

在《电子连接器温升仿真教程 一》中详细介绍了用内热法做电子连接器温升仿真的操作步骤与方法,本教程将讲解用电流电压法做电子连接器温升仿真。 本教程,将以下面产品为例演示温升仿真方法其操作步骤。 该连接器为电池连接器,其Housing材料为LCP+30%GF,端子材质为铍铜…