Apollo里常用的google protobuf简明教程

protobuf(Google Protocol Buffers)是Google提供一个具有高效的协议数据交换格式工具库(类似Json)。

在看百度Apollo自动驾驶开源代码时,经常会看到.proto文件,刚开始不了解是怎么用的,同时在看代码时经常会看到一些找不到定义的类,这个时候往往导致代码看不下去,在简单了解google protobuf 的使用后,问题都迎刃而解。

.proto里的message类数据结构是Apollo里各模块常用的一种数据结构。

后面将Apollo代码里的规划控制相关模块的算法的单元测试单独摘出来的时候也会用的上。

比如这个PathPoint,根据上下文的用法,显然是个路径点数据结构类,但是整个代码都没有找到任何class PathPoint关键词,没有找到这个类的定义,右键转到定义也会提示找不到。

其实这个PathPoint是一个由.proto文件定义的message生成的类,在编译后会生成class PathPoint的定义,proto文件编译后会生成.pb.cc和.pb.h会定义相关message类的数据成员以及操作函数

比如PathPoint类

Protobuf库在ubuntu下的安装步骤略去,介绍下使用

下面以一个简单的例子来说明protobuf在Apollo代码中是如何使用的

环境是ubuntu c++用cmake编译

1.利用proto文件生成.pb.cc和.pb.h文件

简洁方法

一定要注意,多个互相依赖的proto文件要用这种方法生成时,一定要注意那个依赖其他proto文件的proto里的import路径是怎么写的,是以哪个层级为起点的,终端要到那个起点的路径来执行下列命令才能生成互相依赖的proto文件的.cc和.h

#其中 --cpp_out=.代表输出.cc .h路径在当前终端路径下   .代表proto文件所在的那个目录
# ./Test.proto表示根据当前路径下的Test.proto生成相应的message类
#这么操作需要本机安装好protobuf环境
protoc --cpp_out=. ./Test.proto

 首先为建立了一个prototest工程文件夹,下面包含一个build空文件夹,一个CMakeLists,一个main.cc主程序,和一个proto文件夹,proto文件夹下包含一个test.proto文件

现在目标是根据这个test.proto文件生成其定义的数据结构的相关类以及类成员的相关操作函数 ,google protobuf可以将proto文件编译生成xxx.pb.cc和xxx.pb.h文件来定义和声明这个message数据结构类,那么就要在CMakeList上下功夫

CMakeList

进有一个源码文件main.cc,生成可执行文件cppTest于build文件夹中

${PROJECT_SOURCE_DIR}指的就是CMakeList所在的这一级路径

../${PROJECT_SOURCE_DIR}表明CMakeList所在的上一级路径

../../${PROJECT_SOURCE_DIR}表明CMakeList所在的上两级路径

${PROJECT_SOURCE_DIR}/ 表明CMakeList所在的下一级路径

#CMakeList
cmake_minimum_required(VERSION 2.8)
PROJECT (cppTest)
SET(SRC_LIST main.cc)
 
set(proto_dir ${PROJECT_SOURCE_DIR}/proto)
file(GLOB proto_files "${proto_dir}/*.proto")
message(STATUS "Proto Source Dir: ${proto_dir}")
message(STATUS "Proto Source Files: ${proto_files}")
 
#Find required protobuf package
find_package(Protobuf REQUIRED)
if(PROTOBUF_FOUND)
    message(STATUS "protobuf library found")
else()
    message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()
 
#set(PROTO_SRCS ${PROJECT_SOURCE_DIR}/proto/srcs)
#set(PROTO_HDRS ${PROJECT_SOURCE_DIR}/proto/hdrs)
include_directories(${PROTOBUF_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${proto_files})
 
add_executable(cppTest main.cc ${PROTO_SRCS} ${PROTO_HDRS})
 
target_link_libraries(cppTest ${PROTOBUF_LIBRARIES})

main.cc

#include "build/test.pb.h"
#include <iostream>

TargetLane t1;
int main(){
    t1.set_id("123");
    t1.set_start_s(0);
    t1.set_end_s(100);
    std::cout<<"t1.id: "<<t1.id()<<std::endl;
    std::cout<<"t1.start s: "<<t1.start_s()<<std::endl;
    std::cout<<"t1.end s: "<<t1.end_s()<<std::endl;
}

proto文件生成的.pb.cc和.pb.h都生成在build下 ,只要包含这个头文件就可以使用这个类了

2. proto文件生成的数据结构类的简单使用方法

从main.cc里可以看出,对protobuf生成数据结构类进行赋值

#include "build/test.pb.h" //包含生成的protobuf头文件就可以使用该message类数据结构了
#include <iostream>

//test.proto生成了TargetLane这个message类
TargetLane t1; //定义一个实例t1
int main(){
    t1.set_id("123");  //.set_XXX()对数据成员XXX进行赋值
    t1.set_start_s(0);
    t1.set_end_s(100);
    //.XXX()直接访问这个数据结构类的数据成员
    std::cout<<"t1.id: "<<t1.id()<<std::endl;
    std::cout<<"t1.start s: "<<t1.start_s()<<std::endl;
    std::cout<<"t1.end s: "<<t1.end_s()<<std::endl;
}

#include "build/test.pb.h" //包含生成的protobuf头文件就可以使用该message类数据结构了

//.set_XXX()对数据成员XXX进行赋值

 //.XXX()直接访问这个数据结构类的数据成员

3.运行结果

进入build文件夹下,打开终端依次输入

cmake ..

make -j6

./cpptest

从test.proto生成了test.pb.cc和test.pb.h,

实现了test.proto里message数据结构类

 程序输出

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wujiangzhu_xjtu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值