Protobuf适合通用通信,FlatBuffers用于高性能场景;前者需序列化反序列化,后者零拷贝读取快;根据需求选型,流程均为定义schema、生成代码、调用API实现序列化。

在C++中使用Protobuf或FlatBuffers这类数据序列化框架,能高效地将结构化数据序列化为二进制格式,便于存储或网络传输。下面分别介绍如何在C++项目中集成和使用这两种主流序列化工具。
一、Protobuf(Protocol Buffers)使用教程
Protobuf 是 Google 开发的成熟序列化库,支持多种语言,性能优秀,适合需要强类型定义和跨平台通信的场景。
1. 安装 Protobuf 编译器和库在 Ubuntu 上安装:
- sudo apt-get install protobuf-compiler libprotobuf-dev
在 macOS 上可通过 Homebrew:
立即学习“C++免费学习笔记(深入)”;
- brew install protobuf
创建一个 message.proto 文件:
syntax = "proto3";
message Person {
string name = 1;
int32 age = 2;
string email = 3;
}
3. 生成 C++ 代码
运行 protoc 编译器:
- protoc --cpp_out=. message.proto
会生成 message.pb.h 和 message.pb.cc 两个文件。
4. 在 C++ 中使用编写主程序:
#include "message.pb.h" #include5. 编译链接#include int main() { Person person; person.set_name("Alice"); person.set_age(30); person.set_email("alice@example.com"); // 序列化到文件 std::ofstream output("person.bin", std::ios::binary); person.SerializeToOstream(&output); output.close(); // 反序列化 Person person2; std::ifstream input("person.bin", std::ios::binary); person2.ParseFromIstream(&input); input.close(); std::cout << "Name: " << person2.name() << ", Age: " << person2.age() << "\n"; return 0; }
编译时需链接 protobuf 库:
- g++ -o demo demo.cpp message.pb.cc `pkg-config --cflags --libs protobuf`
二、FlatBuffers 使用教程
FlatBuffers 是 Google 推出的零解析(zero-copy)序列化库,读取数据无需反序列化,速度快,内存占用低,适合性能敏感场景如游戏或嵌入式系统。
克隆仓库并编译 flatc 编译器:
git clone https://github.com/google/flatbuffers.git cd flatbuffers cmake -G "Unix Makefiles" make sudo make install2. 定义 .fbs 文件
创建 schema.fbs:
table Person {
name:string;
age:int;
email:string;
}
root_type Person;
3. 生成 C++ 代码
运行 flatc 工具:
- flatc --cpp schema.fbs
生成 schema_generated.h 文件。
4. 在 C++ 中序列化与反序列化示例代码:
#include "schema_generated.h" #include5. 编译链接#include #include int main() { flatbuffers::FlatBufferBuilder builder; auto name = builder.CreateString("Bob"); auto email = builder.CreateString("bob@example.com"); PersonBuilder pb(builder); pb.add_name(name); pb.add_age(25); pb.add_email(email); auto person = pb.Finish(); builder.Finish(person); // 获取 buffer 指针和长度 uint8_t *buf = builder.GetBufferPointer(); size_t size = builder.GetSize(); // 写入文件 std::ofstream output("person.fb", std::ios::binary); output.write(reinterpret_cast (buf), size); output.close(); // 读取并访问(无需解析) std::ifstream input("person.fb", std::ios::binary | std::ios::ate); size_t fileSize = input.tellg(); input.seekg(0, std::ios::beg); std::vector buffer(fileSize); input.read(reinterpret_cast (buffer.data()), fileSize); input.close(); auto p = GetPerson(buffer.data()); std::cout << "Name: " << p->name()->c_str() << ", Age: " << p->age() << "\n"; return 0; }
包含 FlatBuffers 头文件路径,并链接标准库即可:
- g++ -o demo_flat demo_flat.cpp -I/usr/local/include -I.
三、Protobuf 与 FlatBuffers 对比建议
选择哪种框架取决于具体需求:
- Protobuf 更适合通用服务通信,生态完善,支持 JSON 转换,调试方便。
- FlatBuffers 适合高性能场景,读取极快,但写入略复杂,不支持原生 map 类型(新版可用 flexbuffers 扩展)。
两者都需要先定义 schema,再生成代码,集成进 C++ 项目流程清晰。根据延迟要求、数据大小和可维护性权衡选择即可。
基本上就这些。配置好环境、写好 schema、生成代码、调用 API,就能在 C++ 中高效使用序列化功能了。











