侧边栏壁纸
博主头像
Into The Abyss 博主等级

My Life is a Death Race

  • 累计撰写 34 篇文章
  • 累计创建 7 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

protobuf学习

Administrator
2024-03-18 / 0 评论 / 0 点赞 / 563 阅读 / 0 字

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
0

评论区