apollo学习基础之一 [.proto协议文件]
在学习apollo过程,有很多基础知识必须先熟悉了解,否则在阅读代码过程中会很吃力。那么其中对.proto文件的理解和使用,特别、非常的重要。你可以在网上百度一下proto,会出来很多good的博客,讲的非常详细。所以,我这版本,就不写那么详细了。只提炼出常用的。
1.定义概念
proto 也就是protobuf,即protocol buffer( 以下简称protobuf) 是google旗下的一款平台无关,语言无关,可扩展的序列化结构数据格式。很适合用做数据存储和作为不同应用,不用语言之间相互通信的数据交换格式
如果在ubuntu可以上一键安装:
sudo apt-get install protobuf-compiler
2.编写简单proto文件
syntax
=
"proto2"
;
//表明使用protobuf的编译器版本为v2,目前最新的版本为v3
package
apollo.common
;
//声明了一个包名,用来防止不同的消息类型命名冲突,类似于 namespace
/*****************************
导入了一个外部proto文件中的定义,
类似于C++中的 include 只能import当前目录及当前目录的子目录中的proto文件
*****************************/
import
"src/help.proto"
;
message
Info
{
//name 是字段名,1 是字段的标识号,在消息定义中,每个字段都有唯一的一个数字标识号,
//这些标识号是用来在消息的二进制格式中识别各个字段的,一旦开始使用就不能够再改变。
//标识号的范围在:1 ~ 229 - 1,其中[19000-19999]为Protobuf预留,不能使用。
optional
string
name
=
1
;
optional
int32
age
=
2
;
optional
int32
xxx
=
3
;
//xxx 代表任意字段名称,为api 举例方便
}
message
VehicleSignal
{
enum
TurnSignal
{
TURN_NONE =
0
;
TURN_LEFT =
1
;
TURN_RIGHT =
2
;
};
optional
TurnSignal
turn_signal
=
1
;
// lights enable command
optional
bool
high_beam
=
2
;
optional
bool
low_beam
=
3
;
optional
bool
horn
=
4
;
optional
bool
emergency_light
=
5
;
}
3.编译
定义proto文件之后需要用protobuf提供的编译工具将proto文件编译成不同语言的源码,此处使用C++。
protoc -I=./ --cpp_out=./ test.proto
4.简单的测试代码
#include
<stdio.h>
#include
<iostream>
#include
<string>
#include
"test.pb.h"
using namespace std;
int
main
(
int
argc,
char
*
argv[])
{
Info
*
pinfo
=
new
Info
();
pinfo->
set_name
(
"testname"
);
pinfo->
set_age
(
120
);
cout
<<
"info.name="
<<
pinfo->
name
()
<<
", age="
<<
pinfo->
age
()
<<
endl;
delete pinfo;
return
0
;
}
5.使用的API
/*----------------------*/
Info
*
pinfo
=
new
Info
(); 声明
设置
pinfo
->
set_name
(
"testname"
);
pinfo
->
set_age
(
120
);
引用
pinfo
->
name
()
//name 获取字段的值 即testname
pinfo
->
age
()
// age 获取字段的值 即120
/*----------------------*/
has_xxx
()
//判断 xxx 是否有值
clear_xxx
();
//清除 xxx 的值
set_xxx
()
//为 xxx 赋值
mutable_xxx
()
//获取 xxx 字段的指针
release_xxx
()
//清除 xxx 的值,并获取当前 xxx 的指针
特殊用法:
_size:检查有多少个字段
使用index来获取特定的字段
add_方法添加一个新的字段
每个字段都有一个clear_xxx 方法来把字段复位为空状态;
标准消息方法
每个消息还包括一些其他方法用来检查和操作整个消息
bool
IsInitialized
()
const
;
//检查是否所有的requied类型的消息都被设置了
string
DebugString
()
const
;
//返回消息的一个可读类型,debug时很有用
void
CopyFrom
(
const
Person
&
from);
//用给定的值来覆盖消息
void
Clear
();
//把所有元素置回空状态
解析和序列化
最终,protocol buffer类有使用二进制格式来读写消息的方法
bool
SerializeToString
(string
*
output)
const
;
//序列化消息并把字节存储在给定的string类型中,注意字节是二进制类型,而不是text类型,我们只是使用string类型作为一个转换容易
bool
ParseFromString
(
const
string
&
data);
//从string中解析消息
bool
SerializeToOstream
(ostream
*
output)
const
;
//把消息写入一个给定的c++ostream中
bool
ParseFromIstream
(istream
*
input);
//从一个给定的c++ istream中解析消息