一,编译protobuf

首先去github下载最新protobuf的C++的relaease版本:

​release链接​​​ 这里我下载的是​​v3.17.3​

解压到任意文件夹,进入文件夹:

Ubuntu protobuf编译安装并在Qt中使用_ubuntu


编译安装官方提供的有​​教程​

执行如下命令进行编译安装:

安装在/usr/local/protobuf

./configure --prefix=/usr/local/protobuf
make
make check
sudo make install
sudo ldconfig

执行完make install,protobuf的头文件和lib文件则被成功的复制在 /usr/local/protobuf路径下
此时在终端输入如下命令,如果有对应输出则证明编译成功:

protoc

Ubuntu protobuf编译安装并在Qt中使用_ubuntu_02


将动态库添加到环境变量:

vi ~/.bashrc

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/protobuf/lib
export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/protobuf/lib
export PATH=$PATH:/usr/local/protobuf/bin

二,创建.proto文件

.proto作为协议文件进行序列化与反序列化数据
我这里创建了一个robotdata.proto的文件,具体解释在注释中:

syntax = "proto3";

option optimize_for = LITE_RUNTIME;
//命名空间
package robot_data;

//点数据类型
message Point {
double x = 1;
double y = 2;
double theta = 3;
}
//激光数据类型
message LaserData {
sint32 location = 1;
int64 timeStamp = 2;
repeated Point scan = 3;
}
//路径数据类型
message RobotPath {
sint32 location = 1;
int64 timeStamp = 2;
repeated Point path = 3;
}
//机器人数据
message RobotData{
oneof Item{
LaserData laser_data = 1;
RobotPath robot_path =2;
}
}

三,生成protobuf的头文件以及cpp文件:

在.proto路径下打开终端,运行如下命令 :
​​​protoc -I=./ --cpp_out=./ ./*.proto​

-cpp_out指明生成的类文件存放位置
-I 如果多个proto文件之间有互相依赖,生成某个proto文件时,需要import其他几个proto文件,这时候就要用-I来指定搜索目录

./*.proto 生成当前目录下的所有.proto文件

运行命令即可生成.cc文件与.h文件:

Ubuntu protobuf编译安装并在Qt中使用_序列化_03

四,qt导入protobuf库:

如果刚才make install的时候没有改变库的安装目录的话,也就是install在/usr/local目录下
在qt项目.pro文件新增如下两句:

INCLUDEPATH += /usr/local/include/google/protobuf
LIBS += -L /usr/local/lib -lprotobuf

Ubuntu protobuf编译安装并在Qt中使用_c++_04


将刚才生成的.cc和.h添加到项目:

分别在header和source目录右键,点击添加现有文件,将.h文件和.cc文件分别加入项目:

Ubuntu protobuf编译安装并在Qt中使用_c++_05


Ubuntu protobuf编译安装并在Qt中使用_ubuntu_06

五,使用protobuf序列化

导入头文件:

#include "robotdata.pb.h"

使用如下代码序列化并查看序列化结果:

//添加laser数据
robot_data::LaserData *laser_data = dataGrame.mutable_laser_data();
robot_data::Point *point;
laser_data->set_location(-1);
laser_data->set_timestamp(1001);
for(int i=0;i<100;i++){
point = laser_data->add_scan();
point->set_x(0.5);
point->set_y(1.6);
point->set_theta(10);
}
//序列化
std::string binary = dataGrame.SerializeAsString();
QByteArray byte(binary.c_str(),binary.size());

qDebug()<<"byte: "<<byte.toHex(' ');
qDebug()<<"byte size:"<<byte.size()<<" "<<binary.size();

Ubuntu protobuf编译安装并在Qt中使用_qt_07

六,使用protobuf反序列化

//反序列化
if (false == redataGrame.ParseFromString(binary)) {
qDebug()<<"反序列化失败!";
}else{
if(redataGrame.has_laser_data()){
qDebug()<<"反序列化laser location:"<<redataGrame.mutable_laser_data()->location();
qDebug()<<"反序列化laser timestamp:"<<redataGrame.mutable_laser_data()->timestamp();
for(int i=0;i<redataGrame.mutable_laser_data()->scan_size();i++){
qDebug()<<redataGrame.mutable_laser_data()->scan(i).x()<<redataGrame.mutable_laser_data()->scan(i).y();
}
}else{
qDebug()<<"无 laser data";
}
}

Ubuntu protobuf编译安装并在Qt中使用_序列化_08

完整demo地址​​github​