protobuf学习记录

安装

sudo apt-update
sudo apt install -y protobuf-compiler protobuf-c-compiler
syntax = "proto2";

package protoTest; // namespace

  

message Example1 {

// 数字类型的集合

optional string name = 1;

optional int32 age = 2;

message EmbeddedMessage {

optional string stringVal = 1;

optional bytes bytesVal = 2;

} // 字段甚至可以又是一个message

// 字段规则:required -> 字段只能也必须出现 1 次

// 字段规则:optional -> 字段可出现 0 次或1次

// 字段规则:repeated -> 字段可出现任意多次(包括 0)

// 类型:int32、int64、sint32、sint64、string、32-bit ....

// 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字)

// 字段规则 类型 名称 = 字段编号;

  

}

1、syntax 关键字表示使用的protobuf的版本,如不指定则默认使用 “proto2”

2、package关键字 表示“包”,生成目标语言文件后对应C++中的namespace命名空间,用于防止不同的消息类型间的命名冲突

3、message对应C++中的类, 内部包含各种属性, 其中repeated修饰数据类型表示是一个数组的概念

编译

protoc [-I] --xxx_out=OUT_DIR file.proto

protoc --cpp_out=. example.proto
g++ main_test.cpp xxx.pb.cc -o main_test -lprotobuf

这样会报错
必须链接pthread(为什么)参考

g++ main.cpp example.pb.cc -o main_test -lprotobuf -pthread

需要注意的是,message的同级属性的num不能重复

编号也是有范围的,编号只能从`1 ~ 2^29 -1`之间进行取数,其中`19000 ~ 19999`不可取,因为这些编号已经被PB官方征用了!使用了编译就会出错;

参考1

在C++中引用

package定义的命名空间会转换为C++中的namespase命名空间,message定义的类会转换为C++中国class定义的类,同时还会增加一系列与该属性字段相关的方法:

  • clear_xxx(): 清除改字段的值;
  • xxx(): 获取当前字段的值;
  • set_xxx(): 为当前字段设置值;
  • mutable_xxx() :获取当前字段的地址,对于自定义类型来说protoc不会为其生成set_xxx()的方法来设置值,因为它没办法预测用户到底想如何给自定义类型设置值,但是它会生成对应的mutable_xxx()函数,利用mutable_xxx()函数我们可以获取到当前字段的地址,然后再利用字段的内置set_xxx()方法进行对自定义类型中的各个字段进行初始化,对于protobuf内置的类型protoc不会为其生成mutable_xxx()方法,当然string等除外,这些基本类型利用set_xxx()方法就能够设置值了。

序列化与反序列化

![[Pasted image 20240715100645.png]]
![[Pasted image 20240715100654.png]]

项目实例

syntax = "proto2";

package rina.planning;

message TrafficLightState {

enum TLState {

INIT = 0;

LANE_FOLLOW = 1;

APPROACH = 2;

STOP = 3;

UNKNOWN_LIGHT = 4;

CROSSING = 5;

TURN_WAIT = 6;

}

optional TLState tl_state = 1;

}

交通灯信号,定义枚举变量TLState和一个TLState字段tl_state。

看上去项目中的protobuf主要的数据类型是double,bool和enum

在其中添加了一个tl_id的字段,然后测试一下

#include <iostream>

#include <string>

#include <fstream>

#include "example.pb.h"

  

int main()

{

GOOGLE_PROTOBUF_VERIFY_VERSION;

// rina::planning::TrafficLightState state;

rina::planning::TrafficLightState state;

state.set_tl_state(rina::planning::TrafficLightState_TLState_APPROACH);

state.set_tl_id(1);

std::string str; // 创建字符串缓冲区

state.SerializeToString(&str);

std::cout << "序列化结果: " << str << std::endl;

rina::planning::TrafficLightState state2;

state2.ParseFromString(str);

std::cout << "反序列化结果: " << "state: " << state2.tl_state() << "id: " << state2.tl_id()<< std::endl;

return 0;

}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆沙粽子好吃嘛!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值