首页 > 其他分享 >安装、学习protobuf

安装、学习protobuf

时间:2024-05-31 15:23:28浏览次数:18  
标签:p1 protobuf proto 学习 set test 安装 string name

Protobuf是什么?

类似于json的一种数据格式,独立于语言,而且是二进制方式,所以比json更快,而且还可以直接存储一些图、树

序列化和反序列化

持久化(存到磁盘硬盘)领域中,数据存到磁盘叫序列化,从磁盘读取出来叫反序列化
网络传输领域中,数据块转字符串叫序列化,对端把字符串解析为数据块叫反序列化

客户端和服务端如何通信

比如一个结构体三个数据依次发送出去,接收端可能一下接收了三个,是无法处理的(不知道边界)
第二种情况,一次性发送出去,添加标记,这样接收端可以一次性解封装,常采用TLV (Tag Length Value)

Protobuf到底是什么

类似于刚刚说的TLV结构,是一种组织数据的格式,可以把若干数据组织成一块---> 序列化为字符串 --> 发送 --> 字符串被反序列化 --> 解析数据

Protobuf怎么安装?

只演示Linux下的安装过程

  1. github下载tar.gz包

https://github.com/protocolbuffers/protobuf/releases/tag/v21.12

我这里下载的21.12版本,比较老了,但是基本功能都能用

image

  1. 登录Linux服务器安装

先上传到Linux上,一般的ssh工具如Mobaxterm都有这个功能

tar -zxvf your_protobuf_package.tar.gz -C /path/to/you_want

cd /path/to/you_want

  • 需要安装c++编译器,如果其他语言版本的也要安装对应编译器,c++我用的g++编译器!

./configure

make

sudo make install

protoc --version

Protobuf如何使用?

简单示例

  1. 确定要序列化的数据,手动改成protobuf格式
Protobuf类型 c++类型 备注
double double 64位浮点数
float float 32位浮点数
int32 int 32位整数
int64 long 64位整数
uint32 unsigned int 32位无符号整数
uint64 unsigned long 64位无符号整数
sint32 signed int 32位整数,处理负数效率高于int32
sint64 signed long 64位整数,处理负数效率高于int64
bool bool 布尔
string string 字符串必须是utf-8或7-bit ASCII编码
bytes string 多字节语言,比如中文字符,用这个更好
enum enum 枚举
message object of class 自定义消息类型
  1. 根据proto语法,写入后缀proto文件中

test.proto

[root@hcss-ecs-9452 test_proto]# cat test.proto 
/*
struct Person
{
    string name;
    string sex;
    int age;
}
*/
syntax = "proto3";

message Person
{
    string name = 1;
    bytes sex = 2;
    int32 age = 3;
}
  1. protoc命令把proto文件转成c++,包含一个xxx.pb.cc和xxx.pb.h

protoc ./test.proto --cpp_out=./

[root@hcss-ecs-9452 test_proto]# 
[root@hcss-ecs-9452 test_proto]# ls
test.proto
[root@hcss-ecs-9452 test_proto]# protoc ./test.proto --cpp_out=./
[root@hcss-ecs-9452 test_proto]# ls
test.pb.cc  test.pb.h  test.proto
[root@hcss-ecs-9452 test_proto]#
  1. 把产生的c++文件添加到项目中,根据文件中API实现序列化和反序列化

节选test.pb.h ,这部分就是protobuf给出的对name这个数据的处理方式,比如清空 设置 查询 根据地址修改等

enum : int {
    kNameFieldNumber = 1,
    kSexFieldNumber = 2,
    kAgeFieldNumber = 3,
  };
  // string name = 1;
  void clear_name();
  const std::string& name() const;
  template <typename ArgT0 = const std::string&, typename... ArgT>
  void set_name(ArgT0&& arg0, ArgT... args);
  std::string* mutable_name();
  PROTOBUF_NODISCARD std::string* release_name();
  void set_allocated_name(std::string* name);
  private:
  const std::string& _internal_name() const;
  inline PROTOBUF_ALWAYS_INLINE void _internal_set_name(const std::string& value);
  std::string* _internal_mutable_name();

  1. 编写makefile

这里需要注意,protobuf大量使用c++11特性,但是centOS默认安装的是g++4.8.5编译器,可能不支持,需要在编译选项中-std=gnu++11

# 目标文件
TARGET = run

# 源文件
SRC = run.cpp test.pb.cc

# 编译器
CC = g++

# 编译选项
CFLAGS = -I. -lprotobuf -std=gnu++11

# 默认规则
all: $(TARGET)

# 依赖关系
$(TARGET): $(SRC)
        $(CC) $(CFLAGS) $^ -o $@

# 编译.proto文件生成C++源文件和头文件
test.pb.cc test.pb.h: test.proto
        protoc --cpp_out=. $<

# 清理规则
clean:
        rm -f $(TARGET) test.pb.cc test.pb.h

# 防止make删除中间文件
.PHONY: all clean

  1. 编译运行查看

可能要先设置一下环境变量

echo $LD_LIBRARY_PATH

# 如果已经设置过/usr/local/lib就不用往下走了
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib' >> ~/.bashrc

source ~/.bashrc

echo $LD_LIBRARY_PATH
[root@hcss-ecs-9452 test_proto]# ls
Makefile  run.cpp  test.pb.cc  test.pb.h  test.proto
[root@hcss-ecs-9452 test_proto]# make
g++ -I. -L/user/local/lib -lprotobuf -std=gnu++11 run.cpp test.pb.cc -o run
[root@hcss-ecs-9452 test_proto]# ./run
name:Jack
sex:女
age:18

复杂应用

嵌套复合数据类型

新增一个proto文件,后续步骤和上面一致

  • 嵌套结构体直接加,嵌套数组前面加repeated就行,调用时需注意,数组要先add_xxx, set_xxx(0, xx)
[root@hcss-ecs-9452 test_proto]# cat testComplex.proto 
syntax = "proto3";
message Addr
{
    int32 door_num = 1;
    bytes addr     = 2;
}

message Person
{
    repeated string name = 1;
    bytes sex   = 2;
    int32 age   = 3;
    Addr ad     = 4;
}
[root@hcss-ecs-9452 test_proto]# cat run.cpp
#include "testComplex.pb.h"

int main(){

    Person p1;
    p1.add_name();
    p1.set_name(0, "Jack");
    p1.add_name("Tom");
    p1.add_name("sb");
   
    p1.set_sex("女");
    p1.set_age(18);
    p1.mutable_ad()->set_addr("陕西省西安市雁塔区");
    p1.mutable_ad()->set_door_num(999); 
    
    std::string output;
    p1.SerializeToString(&output);
    
    Person p2;
    p2.ParseFromString(output);
    //std::cout << "name:" << p2.name() << std::endl;
    std::cout << "sex:"  << p2.sex() << std::endl;
    std::cout << "age:"  << p2.age() << std::endl;
    std::cout << "addr:" << p2.ad().addr() << p2.ad().door_num() << "号" << std::endl;
    int size = p2.name_size();
    for(int i = 0; i < size; ++i)
    {
        std::cout << "第" << i << "个名字是" << p2.name(i) << std::endl;
    }
    return 0;
}

使用枚举


[root@hcss-ecs-9452 test_proto]# cat testComplex.proto 
syntax = "proto3";
enum Color
{
    red = 0;    //第一个必须是0
    green = 5;  //后面的不必123
    blue = 6;
}
message Addr
{
    int32 door_num = 1;
    bytes addr     = 2;
}

message Person
{
    repeated string name = 1;
    bytes sex   = 2;
    int32 age   = 3;
    Addr ad     = 4;
    Color color = 9;  //这里也可以不写567
}
[root@hcss-ecs-9452 test_proto]# cat run.cpp
#include "testComplex.pb.h"

int main(){

    Person p1;
    p1.add_name();
    p1.set_name(0, "Jack");
    p1.add_name("Tom");
    p1.add_name("sb");
   
    p1.set_sex("女");
    p1.set_age(18);
    p1.mutable_ad()->set_addr("陕西省西安市雁塔区");
    p1.mutable_ad()->set_door_num(999); 
    p1.set_color(Color::red);    
 
    std::string output;
    p1.SerializeToString(&output);
    
    Person p2;
    p2.ParseFromString(output);
    //std::cout << "name:" << p2.name() << std::endl;
    std::cout << "sex:"  << p2.sex() << std::endl;
    std::cout << "age:"  << p2.age() << std::endl;
    std::cout << "addr:" << p2.ad().addr() << p2.ad().door_num() << "号" << std::endl;
    int size = p2.name_size();
    for(int i = 0; i < size; ++i)
    {
        std::cout << "第" << i << "个名字是" << p2.name(i) << std::endl;
    }
    std::cout << "Color:"  << p2.color() << std::endl;
    return 0;
}

proto中导入其他proto文件

import "/path/xxx.proto"

命名空间

package xxx

  • 当其他proto文件调用时:
    xxx.Person p

  • 上述命令会转换为cc文件的namespace

标签:p1,protobuf,proto,学习,set,test,安装,string,name
From: https://www.cnblogs.com/xsl-blogs/p/18223922

相关文章

  • 521源码-免费手游下载-【烽火中原H5】深度体验:横版网页国战手游及WIN学习手工端
    【烽火中原H5】深度体验:横版网页国战手游及WIN学习手工端全面解析,烽火中原H5】横板网页国战手游+WIN学习手工端+语音视频教程+营运后台+CDK授权后台,喜欢国战手游的玩家们,你们期待已久的【烽火中原H5】现已上线!这款游戏以横版网页的形式呈现,为玩家带来沉浸式的国战体验。同时......
  • 2024年网络安全学习指南!详尽路线图,从零基础到黑客高手的进阶之路!
    零基础小白,到就业!入门到入土的网安/黑客学习路线!建议的学习顺序:一、网络安全学习普法(心里有个数,要进去坐几年!)1、了解并介绍《网络安全法》2、《全国人大常委会关于维护互联网安全的决定》3、《中华人民共和国计算机信息系统安全保护条例(2011年修正)》4、《中华人民共......
  • windows下用vmware安装的mac虚拟机更改分辨率踩坑日记
    折腾了很久,终于把mac虚拟机安装上了!首先用unlocker解锁vmware安装macos!然后从网上下载苹果系统的安装包!注意,不要dmg镜像,要cdr格式的!装好后觉得分辨率太小!想更改分辨率!于是百度!网上说的修改com.apple.Boot.plist文件根本行不通啊!苹果限制了你修改这个文件,因为新版本的系统没有......
  • U盘安装mac系统
    https://sysin.org/blog/macOS-Monterey/  1、一台Mac电脑 2、一个U盘(容量不小于8GB) 3、最新的Mac系统安装文件(可在AppStore下载)步骤:1、准备U盘:首先,将U盘插入Mac电脑的USB接口。请注意,插入U盘前确保其中没有重要数据,因为重装系统会将U盘上的所有数据清空。 2、格式......
  • m1安装cocoapods
    m1安装cocoapodshttp://www.taodudu.cc/news/show-5551017.html?action=onClick podsearchAFNetworking[!]Unabletofindapodwithname,author,summary,ordescriptionmatching`AFNetworking`podrepo返回也是0repo解决方法使用国内清华cocoapod源手动下载......
  • windows在anaconda中下载安装fasttext
    fasttext的github官网:https://github.com/facebookresearch/fastText1.访问fasttext-wheel,点击对应链接,下载对应Python版本、操作系统类型的.whl文件:2.打开anaconda终端,切换到上面的.whl文件的工作目录,运行pip安装命令,指定安装文件:pipinstallfasttext_wheel-0.9.2-cp38-cp......
  • C3P0链学习
    c3P0链学习目录c3P0链学习URLClassLoader远程类加载出网利用条件逆向分析正向分析总结复现漏洞C3P0之JNDI注入出网利用条件发现者视角正向分析漏洞复现C3P0之hex序列化不出网利用条件正向分析漏洞复现C3P0不出网无依赖的利用C3P0是一个开源的JDBC连接池,它实现了数据源......
  • Stable diffusion 4.8+ComfyUI升级版终于来了!(一键安装包,感谢大佬)
    如果这个世界有上帝,那么祂一定是程序员。国内SD绘画启动器第一人是我认为是B站的秋葉aaaki因为制作了这款StableDiffusion启动器,降低了国内使用SD的门槛且分文不收,秋叶被粉丝戏称赛博菩萨。1背景信息▍****StableDiffusion是什么?StableDiffusion(简称SD)是一种生......
  • Stable Diffusion下载安装,保姆级教程指南!
    目录1、StableDiffusion简介2、StableDiffusion电脑配置3、StableDiffusion安装步骤4、其它一、了解StableDiffusion1、StableDiffusion(简称SD)是一种图像生成模型,主要用于生成以文本生成图像,图片生成图片,图片修复等,由慕尼黑路德维希马克西米利安大学CompVis小组......
  • 美团多场景多任务学习论文《HiNet: Novel Multi-Scenario & Multi-Task Learning with
    模型结构模型主要包含场景抽取层和任务抽取层(上图A):场景抽取层场景抽取层主要包括了场景共享专家(Scenario-sharedexpert)模块、当前场景特有专家(Scenario-specificexpert)模块以及场景感知注意力网络,通过这三部分的信息抽取,最终形成了场景层次的信息表征场景共享专家就是一......