0%

protobuf tutorial

Series

Guide

intro

如果proto结构体的变量是基础变量,比如int、string等等,那么set的时候直接调用set_xxx即可。
如果变量是自定义类型,那么C++的生成代码中,就没有set_xxx函数名,取而代之的是三个函数名:

  • set_allocated_xxx() 传入参数必须是new出来的指针,protobuf内部会自动释放
  • release_xxx()
  • mutable_xxx()mutable_xxx()函数内部new一个对象并返回对象地址,后续可以赋值

user-defined field

protobuf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
syntax = "proto2";

package kezunlin.proto;

message Vector3D{
optional float x = 1;
optional float y = 2;
optional float z = 3;
}

message PlayerPos{
optional uint32 id = 1;
optional Vector3D pos = 2;
}

demo.pb.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// optional uint32 id = 1;
bool has_id() const;
void clear_id();
static const int kIdFieldNumber = 1;
::google::protobuf::uint32 id() const;
void set_id(::google::protobuf::uint32 value);

// optional .kezunlin.proto.Vector3D pos = 2;
bool has_pos() const;
void clear_pos();
static const int kPosFieldNumber = 2;
public:
const ::kezunlin::proto::Vector3D& pos() const;
::kezunlin::proto::Vector3D* release_pos();
::kezunlin::proto::Vector3D* mutable_pos();
void set_allocated_pos(::kezunlin::proto::Vector3D* pos);

基础类型字段id通过id()set_id()操作;
自定义类型字段pos通过pos(),set_allocated_pos(),release_pos(),mutable_pos()操作;

usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PlayerPos player;
player.set_id(100);

// method 1
Vector3D *pos = new Vector3D();
pos->x = 1;
pos->y = 2;
pos->z = 3;
player.set_allocated_pos(pos);

// method 2
Vector3D *pos = player.mutable_pos();
pos->x = 1;
pos->y = 2;
pos->z = 3;

总结:对于自定义类型

  • 使用set_allocated_xxx,赋值的对象需要new出来,不能用局部的,这里保存的是对象的指针。
  • 使用mutable_xxx,赋值时候,可以使用局部变量,因为在调用的时,内部做了new操作。

repeated field

protobuf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
syntax = "proto2";

package kezunlin.proto;

message LidarPoint {
optional double x = 1; // in meters.
optional double y = 2; // in meters.
optional double z = 3; // height in meters.
optional double intensity = 4; // lidar intensity
}

message PointCloud {
optional uint64 timestamp_msec = 1; // Header
repeated LidarPoint points = 2; // lidar point cloud
}

point_cloud.pb.h

1
2
3
4
5
6
7
8
9
10
11
// repeated .kezunlin.proto.LidarPoint points = 2;
int points_size() const;
void clear_points();
static const int kPointsFieldNumber = 2;
::kezunlin::proto::LidarPoint* mutable_points(int index);
::google::protobuf::RepeatedPtrField< ::kezunlin::proto::LidarPoint >*
mutable_points();
const ::kezunlin::proto::LidarPoint& points(int index) const;
::kezunlin::proto::LidarPoint* add_points();
const ::google::protobuf::RepeatedPtrField< ::kezunlin::proto::LidarPoint >&
points() const;

usage

使用add_xxx来新建对象

1
2
3
4
5
6
7
kezunlin::proto::PointCloud pc;

LidarPoint* pt = pc.add_points();
pt->set_x(1);
pt->set_y(2);
pt->set_z(3);
pt->set_intensity(1);

Reference

History

  • 20190117: created.