说说C++ 序列化 Protocol Buffers:高效数据交换

最近在折腾项目的时候碰到了这个知识点,查了不少资料,索性整理出来分享给大家。

目录

1.简介

2.安装

2.1.快速安装

2.2.源码编译安装

3.C++中使用流程

3.1.定义 Protobuf 数据结构(.proto 文件)

3.2.编译生成 C++ 代码

3.3.编写 C++ 业务代码

3.4.编译和链接

4.核心用法详解

5.注意事项

6.Protobuf vs 其他序列化方案

7.总结


1.简介

         Protocol Buffers(简称 Protobuf) —— Google 开发的一种语言无关、平台无关、可扩展的结构化数据序列化协议。相比 JSON/XML,它体积更小、速度更快、兼容性更强,是微服务、网络通信、数据存储的首选序列化方案。

        特点有:

  • 高效:二进制序列化,体积比 JSON 小 3-10 倍,速度快 20-100 倍;
  • 强类型:编译期检查数据类型,避免运行时错误;
  • 兼容:向后 / 向前兼容,新增字段不影响旧代码;
  • 跨语言:一套 .proto 定义,生成 C++/Java/Python/Go 等代码;非常适合多语言微服务架构。

2.安装

2.1.快速安装

系统安装命令Ubuntu/Debiansudo apt install protobuf-compiler libprotobuf-devmacOSbrew install protobufWindowsvcpkg install protobuf protobuf:x64-windows

验证安装:

protoc --version  # 查看编译器版本,成功输出则安装完成

2.2.源码编译安装

git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf
git checkout v3.21.12  # 选择稳定版本
mkdir build && cd build
cmake ..
make -j$(nproc)
sudo make install

3.C++中使用流程

3.1.定义 Protobuf 数据结构(.proto 文件)

创建 person.proto,这是 Protobuf 的接口定义文件,所有数据结构都在这里声明(推荐使用 proto3 语法,更简洁):

// 指定语法版本(必须写在第一行)
syntax = "proto3";

// 生成的 C++ 代码命名空间
package tutorial;

// 定义消息体(对应 C++ 类)
message Person {
  // 字段规则:字段类型 字段名 字段编号(必须唯一)
  string name = 1;    // 姓名
  int32 age = 2;      // 年龄
  string email = 3;   // 邮箱

  // 嵌套枚举类型
  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  // 嵌套消息类型
  message PhoneNumber {
    string number = 1;
    PhoneType type = 2;
  }

  // 重复字段(对应 C++ 容器,存储多个手机号)
  repeated PhoneNumber phones = 4;
}

关键语法说明:

  • 字段编号 :每个字段后的 = 1= 2 是唯一的字段标识符,一旦定义就不能更改,这是向后兼容性的关键。
  • 字段规则
singular (默认):0 或 1 个值
  • repeated :0 或多个值(类似 C++ 的 vector
  • optional (proto2 或 proto3 2023+):可选字段
  • required (仅 proto2):务必字段
数据类型

int32int64uint32uint64sint32sint64fixed32fixed64sfixed32sfixed64floatdoubleboolstringbytes、枚举、其他消息类型。

3.2.编译生成 C++ 代码

使用 protoc 编译器将 .proto 文件编译为 C++ 头文件和源文件:

# --cpp_out=. :生成 C++ 代码到当前目录
protoc --cpp_out=. person.proto

执行后会生成两个文件:

  • person.pb.h:头文件(声明类、方法)
  • person.pb.cc:源文件(实现序列化 / 反序列化)

3.3.编写 C++ 业务代码

创建 main.cpp,实现对象赋值、序列化、反序列化核心逻辑:

```

include


include


include


// 引入Protobuf生成的头文件

include "person.pb.h"

// 序列化:Person对象 → 二进制字符串
void Serialize(const tutorial::Person& person, std::string& data) {
person.SerializeToString(&data);
}

// 反序列化:二进制字符串 → Person对象
void Deserialize(tutorial::Person& person, const std::string& data) {
person.ParseFromString(data);
}

int main() {
// 1. 初始化Protobuf(务必调用,全局仅一次)
GOOGLE_PROTOBUF_VERIFY_VERSION;

// ========== 2. 构造Person对象 ==========
tutorial::Person person;
person.set_name("张三");
person.set_age(25);
person.set_email("zhangsan@test.com");

// 添加重复字段(手机号)
auto phone1 = person.add_phones();
phone1->set_number("13800138000");
phone1->set_type(tutorial::Person::MOBILE);

auto phone2 = person.add_phones();
phone2->set_number("010-12345678");
phone2->set_type(tutorial::Person::HOME);

// ========== 3. 序列化 ==========
std::string serialized_data;
Serialize(person, serialized_data);
std::cout


暂时整理到这里。以上都是个人理解,可能有疏漏,欢迎指正。

评论 (0)

暂无评论