C++如何使用Protobuf进行数据序列化?(入门教程)

Protobuf序列化C++数据需三步:写.proto文件定义结构→用protoc生成C++类→在代码中创建、序列化和解析对象;示例含环境安装、person.proto定义、生成person.pb.h/cc及main.cpp序列化/反序列化流程。

用 Protobuf 序列化 C++ 数据,核心是三步:写 .proto 文件定义结构 → 用 protoc 编译生成 C++ 类 → 在代码中创建、序列化和解析对象。

1. 安装 Protobuf 并准备环境

确保系统已安装 protoc 编译器和 C++ 运行时库:

  • Linux/macOS:推荐用包管理器安装(如 apt install protobuf-compiler libprotobuf-devbrew install protobuf
  • Windows:下载预编译二进制包,把 protoc.exe 加入 PATH,并链接 libprotobuf.lib
  • 验证:终端运行 protoc --version,应输出类似 libprotoc 3.21.12

2. 编写 .proto 文件定义数据结构

新建 person.proto,描述一个简单联系人:

syntax = "proto3";
package tutorial;

message Person {
  string name = 1;
  int32 id = 2;
  string email = 3;
  repeated string phone = 4;
}

注意点:

  • syntax = "proto3" 是必须声明
  • package 防止命名冲突,会映射为 C++ 命名空间
  • 字段编号(= 1, = 2)不能重复,建议从 1 开始连续编号
  • repeated 表示可变长数组(对应 std::vector

3. 生成 C++ 代码

执行命令生成头文件和源文件:

protoc --cpp_out=. person.proto

会生成 person.pb.hperson.pb.cc。在项目中包含头文件并链接 protobuf 库即可使用。

编译时需加链接选项:-lprotobuf(g++ 示例):

g++ main.cpp person.pb.cc -lprotobuf -o demo

4. 在 C++ 中序列化与反序列化

以下是最简完整示例:

#include "person.pb.h"
#include 
#include 

int main() {
  tutorial::Person person;
  person.set_name("Alice");
  person.set_id(123);
  person.set_email("alice@example.com");
  person.add_phone("123-4567");

  // 序列化到文件
  std::ofstream output("person.dat", std::ios::binary);
  person.SerializeToOstream(&output);

  // 反序列化
  tutorial::Person restored;
  std::ifstream input("person.dat", std::ios::binary);
  restored.ParseFromIstream(&input);

  std::cout << restored.name() << ", " << restored.id() << "\n";
  return 0;
}

关键方法说明:

  • set_XXX() 设置标量字段(如 set_name()
  • add_XXX() 添加 repeated 字段元素(如 add_phone()
  • SerializeToOstream() 写入二进制流(高效紧凑)
  • ParseFromIstream() 从二进制流读取并填充对象
  • 所有 getter 方法(如 name(), phone(i))默认返回 const 引用,安全高效

不复杂但容易忽略:每次修改 .proto 后都要重新运行 protoc;C++ 类是值语义,支持拷贝、赋值和移动;序列化结果是二进制,不可读但体积小、速度快。