protobuf简介
Protocol Buffers (protobuf) 是一种由 Google 开发的数据序列化格式,用于在不同进程之间进行数据交换,通常用于通信协议、数据存储等领域。
Protocol Buffers 使用二进制格式,相比 XML 和 JSON,它的编码和解码速度更快,且生成的数据更小。
Protocol Buffers 支持多种编程语言(如C++、Java、Python、Go等),因此可以在不同语言之间轻松地传递数据。
支持向前和向后兼容的数据结构更新,通过版本控制,使得对数据结构的修改不会影响已经部署的系统。
linux编译
# 下载解压protobuf-21.12源码
wget https://github.com/protocolbuffers/protobuf/releases/download/v21.12/protobuf-all-21.12.tar.gz
tar -zxvf protobuf-all-21.12.tar.gz
# 编译安装
cd protobuf-21.12/
./configure --prefix=/home/pjw6/Documents/self_lib/protobuf #--prefix可以指定为你要安装的目录,默认为/usr/local目录,我不太喜欢将第三方库直接安装在系统目录中
make -j12
make install
# 测试
/home/pjw6/Documents/self_lib/protobuf/bin/protoc --version
# 如果成功输出版本号,如libprotoc 3.21.12,则安装成功
用法
message
:定义消息类型,类似于结构体或对象。对于可维护性和可读性来说,尽量保持与文件名一致
string, int32
:字段类型,支持多种基本数据类型。
repeated
:定义重复的字段,类似于数组或列表。
enum
:定义枚举类型,第一个元素编号必须为0。
syntax
:指定所使用的 protobuf 语法版本,一般为”proto3“,每个proto文件必需。
import
:导入其他包,导入语句通常在文件的开头声明。
package
:使用命名空间,包名的声明也通常在文件的开头,但必须在导入语句之后。
示例
address.proto
syntax = "proto3";
message address{
int32 num = 1;
bytes addr = 2;
}
person.proto
syntax = "proto3";
import "address.proto";
enum Color{
red = 0;
green = 1;
blue = 2;
dark = 3;
}
message person{
int32 id= 1;
repeated bytes name = 2;
bytes sex = 3;
int32 age = 4;
address addr = 5;
Color color = 6;
}
使用protoc编译proto文件生成代码
#在proto文件的目录下使用上面的安装目录的protoc程序进行编译,如果安装的系统目录下可以直接protoc
/home/pjw6/Documents/self_lib/protobuf/bin/protoc address.proto --cpp_out=./
/home/pjw6/Documents/self_lib/protobuf/bin/protoc person.proto --cpp_out=./
这样应该就可以成功生成对应的.cc和.h文件,可以在自己的项目中进行调用。
测试
main.cpp
#include "person.pb.h"
#include <iostream>
int main(int argc, char const *argv[])
{
person p;
p.set_id(10);
p.set_age(42);
p.set_color(blue);
p.set_sex("man");
p.add_name();
p.add_name("路飞");
p.add_name("艾斯");
p.add_name("萨博");
p.mutable_addr()->set_addr("陕西省西安市");
p.mutable_addr()->set_num(4);
std::string output;
p.SerializeToString(&output);
person pp;
pp.ParseFromString(output);
std::cout<<pp.id()<<" "<<pp.age()<<" "<<pp.sex()<<" "<<std::endl;
std::cout<<pp.addr().addr()<<" "<<pp.addr().num()<<std::endl;
int size = pp.name_size();
for(int i = 0;i<size;i++){
std::cout<<pp.name(i)<<" ";
}
std::cout<<std::endl;
std::cout<<pp.color()<<std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.22)
project(test)
set(CMAKE_CXX_STANDARD 17)
set(PROTOBUF_SOURCE_DIR /home/pjw6/Documents/self_lib/protobuf) # 修改为你安装的目录
# 添加头文件查找目录
include_directories(${PROTOBUF_SOURCE_DIR}/include)
# 添加链接库目录
link_directories(${PROTOBUF_SOURCE_DIR}/lib)
aux_source_directory(./ SRC)
add_executable(test ${SRC})
target_link_libraries(test protobuf)
编译执行
mkdir build
cd build
cmake ..
make
./test
评论区