安装ProtoBuf
1.安装依赖
sudo apt-get install autoconf automake libtool curl make g++ -y
默认需要安装这些,按需安装
2.找到相对应的版本
使用的是3.21.12https://github.com/protocolbuffers/protobuf/releases/tag/v21.12
wget https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protobuf-all-21.12.tar.gz
如果下载的.tar.gz结尾的包
tar -zxvf protobuf-all-21.12.tar.gz
如果下载的是.tar结尾的包
tar -xf protobuf-all-21.12.tar
3.进入到protobuf-all-21.12
cd protobuf-21.12/
如果下的的某一版本(不执行下面这一步,我下载的是全部版本需要执行这一步)
./autogen.sh
4.开始编译
指定安装的位置
./configure --prefix=/usr/local/protobuf
这个是指定位置,我是放到/usr/local/protobuf下
开始编译
make 编译的时间很慢
sudo make install
5.检查
cd /usr/local/protobuf/bin
./protoc --version
如果能看到他的版本则,安装成功
6.添加到环境变量
gedit ~/.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/
#c程序头⽂件搜索路径
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/local/protobuf/include/
#c++程序头⽂件搜索路径
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/usr/local/protobuf/include/
#pkg-config 路径
export PKG_CONFIG_PATH=/usr/local/protobuf/lib/pkgconfig/
source ~/.bashrc
7.检查
protoc --version
libprotoc 3.21.12
如果出现这个版本信息则安装成功。
注:此版本之后的编译方法有变化,参考如下链接
使用bazel编译protobuf构建c++项目 - 知乎 (zhihu.com)
使用Protobuf
1.什么是Protobuf
XML和JSON是目前常用的数据交换格式,它们直接使用字段名称维护序列化后类实例中字段与数据之间的映射关系,一般用字符串的形式保存在序列化后的字节流中。消息和消息的定义相对独立,可读性较好。但序列化后的数据字节很大,序列化和反序列化的时间较长,数据传输效率不高。
Protobuf是Google提供一个具有高效的协议数据交换格式工具库,类似于JSON,Protobuf和XML、JSON序列化的方式不同,采用了二进制字节的序列化方式,用字段索引和字段类型通过算法计算得到字段之前的关系映射,从而达到更高的时间效率和空间效率,特别适合对数据大小和传输速率比较敏感的场合使用。
以下是Protocol Buffers的一些关键特性和概念:
①语言无关:Protobuf不依赖于特定的编程语言,这意味着您可以使用一个简单的语言无关接口描述语言(IDL)定义数据结构,然后生成适用于各种编程语言的代码来处理这些结构。
②数据结构定义:Protobuf使用结构化模式定义语言来定义要序列化的数据的结构。这个模式被编写在一个.proto文件中,它定义了数据结构的字段、类型和可选元数据。
③紧凑的二进制格式:Protobuf将结构化数据序列化为二进制格式,这种格式比传统的基于文本的格式(如XML或JSON)更紧凑和高效。较小的大小减少了带宽和存储需求,使其非常适用于网络通信或存储大量数据。
④高效的编码和解码:Protobuf使用高效的编码和解码机制,可以快速地对数据进行序列化和反序列化。二进制格式经过了优化,以提高速度,生成的代码提供了方便的API来处理序列化的数据。
⑤版本控制和向后兼容性:Protobuf支持版本控制和向后兼容性。可以随着时间的推移演进数据模式,通过修改模式来适应新的需求,同时保持与旧版本数据的兼容性。
Protobuf具有许多其他功能和优点,例如可扩展性、跨平台支持和代码生成。它被广泛应用于各种领域,包括分布式系统、网络通信、数据存储和交换等。
2. Protobuf有什么
Protobuf 提供了C++、java、python语言的支持(C需要protobuf-c),提供了windows(proto.exe)和linux平台可执行文件及源文件。Protobuf序列化数据时,常常需要一个proto文件,proto文件定义了协议数据中的数据结构,内容举例如下所示:
syntax = "proto2"; // proto3 必须加此注解
package contacts; //服务前缀,包名,防止冲突
option optimize_for = LITE_RUNTIME; //optimize_for是文件级别的选项,Protocol Buffer定义三种优化级别SPEED/CODE_SIZE/LITE_RUNTIME
//缺省情况下是SPEED。
//SPEED: 表示生成的代码运行效率高,但是由此生成的代码编译后会占用更多的空间。
//CODE_SIZE: 和SPEED恰恰相反,代码运行效率较低,但是由此生成的代码编译后会占用更少的空间,通常用于资源有限的平台,如Mobile。
//LITE_RUNTIME: 生成的代码执行效率高,同时生成代码编译后的所占用的空间也是非常少。 这是以牺牲Protocol Buffer提供的反射功能为代价的
// 定义联系人message
message PeopleInfo {
string name = 1; // 姓名
int32 age = 2; // 年龄
}
3.测试例子
做成如上内容文件test.proto
运行protoc –cpp_out=./ test.proto
protoc:编译命令
–cpp_out:表示生产的是c++代码
=号后面的点:表示生成的文件放在当前目录下
test.proto:表示编译的文件
在当前目录下生成test.pb.h 和test.pb.cc文件
使用c++对Test数据进行读写,编写test.cc
#include <iostream>
#include "test.pb.h"
int main() {
std::string people_str;
{
// 对⼀个联系⼈的信息使⽤ PB 进⾏序列化,并将结果打印出来。
contacts::PeopleInfo people;
people.set_name("张三");
people.set_age(20);
if (!people.SerializeToString(&people_str)) {
std::cerr << "序列化联系⼈失败!" << std::endl;
return -1;
}
std::cout << "序列化成功,结果:" << people_str << std::endl;
}
{
// 对序列化后的内容使⽤ PB 进⾏反序列,解析出联系⼈信息并打印出来。
contacts::PeopleInfo people;
if (!people.ParseFromString(people_str)) {
std::cerr << "反序列化联系⼈失败!" << std::endl;
return -1;
}
std::cout << "反序列化成功!" << std::endl
<< "姓名: " << people.name() << std::endl
<< "年龄: " << people.age() << std::endl;
}
return 0;
}
编译使用 g++ test.pb.h test.pb.cc test.cc -o test -lprotobuf -lpthread
执⾏ Test
,可以看⻅people经过序列化和反序列化后的结果:
./test
# 打印如下说明成功了
序列化成功,结果:
张三
反序列化成功!
姓名: 张三
年龄: 20