ubuntn 20.04
protobuf v3.19.4
这里有两种方式安装,一种是通过apt方法安装,另外一种是通过下载源码进行编译安装,这里使用编译源码安装方式
版本为tobuf v3.19.4
sudo wget https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/protobuf-all-3.19.4.tar.gz
2.解压protobuf-all-3.19.4.tar.gz
sudo tar -zxvf protobuf-all-3.19.4.tar.gz
3.编译安装
cd protobuf-3.19.4
sudo ./autogen.sh
sudo ./configure --prefix=$INSTALL_DIR #--prefix指定安装目录
sudo make
sudo make check
sudo make install
4、配置环境变量和动态连接库
更改环境变量:
vim /etc/profile
在文件的末尾添加如下的两行: (把bin路径和pkgconfig路径添加到系统PATH)
export PATH= P A T H : PATH: PATH:INSTALL_DIR/bin/
export PKG_CONFIG_PATH=$INSTALL_DIR/lib/pkgconfig/
配置动态链接库
vim /etc/ld.so.conf
在文件中添加/usr/local/protobuf/lib(注意: 在新行处添加)
$INSTALL_DIR/lib
更改完成之后ldconfig即可
5、查看是否安装成功
protoc --version
写个简单例子的需求:
我打算使用 Protobuf 和 C++ 开发一个十分简单的例子程序。该程序由两部分组成。第一部分被称为 Writer,第二部分叫做 Reader。Writer 负责将一些结构化的数据写入一个磁盘文件,Reader 则负责从该磁盘文件中读取结构化数据并打印到屏幕上。
备用于演示的结构化数据是 HelloWorld,它包含两个基本数据:
.proto文件如下:
package lm;
message helloworld
{
required int32 id = 1; // ID
required string str = 2; // str
optional int32 opt = 3; //optional field
}
一个比较好的习惯是认真对待 proto 文件的文件名。比如将命名规则定于如下:
packageName.MessageName.proto
在上例中,package 名字叫做 lm,定义了一个消息 helloworld,该消息有三个成员,类型为 int32 的 id,另一个为类型为 string 的成员 str。opt 是一个可选的成员,即消息中可以不包含该成员。
写好 proto 文件之后就可以用 Protobuf 编译器将该文件编译成目标语言了。本例中我们将使用 C++。
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/XXX.proto
命令将生成两个文件:
lm.helloworld.pb.h , 定义了 C++ 类的头文件
http://lm.helloworld.pb.cc , C++ 类的实现文件
在生成的头文件中,定义了一个 C++ 类 helloworld,后面的 Writer 和 Reader 将使用这个类来对消息进行操作。诸如对消息的成员进行赋值,将消息序列化等等都有相应的方法。
writer部分代码如下:
#include "lm.helloworld.pb.h"
#include
#include
using namespace std;
int main()
{
lm::helloworld msg1;
msg1.set_id(101);
msg1.set_str("hello");
// Write the new address book back to disk.
fstream output("./log", ios::out | ios::trunc | ios::binary);
if (!msg1.SerializeToOstream(&output)) {
cerr << "Failed to write msg." << endl;
return -1;
}
std::cout << "write msg to disk success"<
编译命令:
g++ writer.cpp lm.helloworld.pb.cc -I/home/yanjun/share/protobufInstallDir/include -L/home/yanjun/share/protobufInstallDir/lib -lprotobuf -o writer
reader部分代码:
#include
#include
#include "lm.helloworld.pb.h"
using namespace std;
void ListMsg(const lm::helloworld &msg)
{
cout << msg.id() << std::endl;
cout << msg.str() << std::endl;
}
int main()
{
lm::helloworld msg1;
{
fstream input("./log", ios::in | ios::binary);
if (!msg1.ParseFromIstream(&input)) {
cerr << "Failed to parse address book." << endl;
return -1;
}
}
ListMsg(msg1);
return 0;
}
编译命令:
g++ reader.cpp lm.helloworld.pb.cc -I/home/yanjun/share/protobufInstallDir/include -L/home/yanjun/share/protobufInstallDir/lib -lprotobuf -o reader
运行 Writer 和 Reader 的结果如下:
>writer
>reader
101
Hello
Reader 读取文件 log 中的序列化信息并打印到屏幕上。本文中所有的例子代码都可以在附件中下载。您可以亲身体验一下。
这个例子本身并无意义,但只要您稍加修改就可以将它变成更加有用的程序。比如将磁盘替换为网络 socket,那么就可以实现基于网络的数据交换任务。而存储和交换正是 Protobuf 最有效的应用领域。
1、https://zhuanlan.zhihu.com/p/141415216
2、https://huaweicloud.csdn.net/63566cf2d3efff3090b5f4d1.html#devmenu7