在前面的学习里,我已经多次接触“序列化”这个概念。
之前一直用 JSON,但很快会遇到两个问题:
- 文本体积大,传输效率低
- 解析性能一般
因此接下来需要学习Protocol Buffers(Protobuf),它是 Google 提供的一种高效二进制序列化协议,也是后续 brpc 的基础组件。
这一篇不讲复杂语法,只做一件事:
用 C++ 跑通 Protobuf 最小闭环:
定义结构 → 生成代码 → 序列化 → 反序列化
先把“能用”跑起来,再谈语法细节。
一、什么是序列化(结合我的理解)
在网络传输或持久化存储中:
- 序列化:把内存中的对象 → 转换成二进制数据
- 反序列化:把二进制数据→ 还原成对象
以前如果自己写类:
classPerson{string name;intage;// 还要自己写 encode() / decode()}需要手动实现一堆get/set和序列化逻辑,繁琐且容易出错。
Protobuf 的核心思想就是:
我只需要写结构描述文件
.proto
编译器自动生成 C++ 类 + 序列化 / 反序列化方法
这就是它高效的关键。
二、编写.proto文件
创建contacts.proto:
syntax = "proto3"; package contacts; message PeopleInfo { string name = 1; // 字段编号标识 int32 age = 2; }我目前理解的几个点
package类似 C++ 命名空间message就是结构体 / 类= 1, =2是字段编号,用于二进制编码标识字段- Protobuf 最终序列化生成的是紧凑二进制数据,不是文本
这一步只是描述结构,真正的 C++ 类还没生成。
三、通过 protoc 生成 C++ 代码
执行命令:
protoc --cpp_out=. contacts.proto会生成两个文件:
contacts.pb.h contacts.pb.cc它们就是:
- 自动生成的 C++ 类定义
- 自动生成的序列化 / 反序列化实现
从这一刻起,我们不需要自己写任何 encode/decode 代码。
这也是 Protobuf 的关键特性:
依赖 .proto → 生成头文件和源文件 → 直接使用生成类
四、编写测试程序
下面是我跑通的完整测试代码。
main.cc:
#include<iostream>#include"contacts.pb.h"intmain(){std::string person_str;// 构造对象并序列化contacts::PeopleInfo person;person.set_name("Alice");person.set_age(20);if(!person.SerializeToString(&person_str)){std::cerr<<"Failed to serialize person."<<std::endl;return-1;}std::cout<<"Serialized PeopleInfo: "<<person_str<<std::endl;// 反序列化contacts::PeopleInfo deserialized_person;if(!deserialized_person.ParseFromString(person_str)){std::cerr<<"Failed to deserialize person."<<std::endl;return-1;}std::cout<<"Deserialized PeopleInfo: name="<<deserialized_person.name()<<", age="<<deserialized_person.age()<<std::endl;return0;}这里的重点是:
SerializeToString()→ 把对象序列化成二进制字符串ParseFromString()→ 把二进制数据还原成对象
整个过程我没有写任何序列化逻辑,全部由生成代码完成。
五、编译运行
编译命令:
g++ -o main main.cc contacts.pb.cc -std=c++11 -lprotobuf运行后输出:
可以看到:
- 控制台打印的序列化结果是不可读的二进制数据
- 但反序列化后对象完整还原
说明整个 Protobuf 工作链路已经跑通。
六、小结
到这里,一个最小 Protobuf C++ 闭环已经完成:
流程总结:
.proto 描述结构 ↓ protoc 生成 .pb.h / .pb.cc ↓ 程序中直接使用生成类 ↓ SerializeToString → 二进制数据 ↓ ParseFromString → 还原对象关键理解点:
- Protobuf 的序列化结果是紧凑二进制数据
- 不需要手写任何序列化逻辑
- 一切依赖
.proto生成的 C++ 源文件
这篇目的是为了让大家快速上手
接下来我会继续分享PB的更多细节 ^ ^