Protobuf C++如何将对象序列化至std::vector<uint8_t>类型
Protobuf序列化返回std::vector<uint8_t>实现方案
核心实现逻辑利用了std::vector底层连续存储的特性,直接将序列化数据写入预分配好的vector缓冲区,不需要额外内存拷贝,性能和原生char数组写入一致。
完整实现代码
#include <vector> #include <google/protobuf/message.h> std::vector<uint8_t> serialize_protobuf(const google::protobuf::Message& msg) { // 校验protobuf对象必填字段是否已完成赋值 if (!msg.IsInitialized()) { return {}; } // 获取序列化后的总字节长度 const size_t buf_size = msg.ByteSizeLong(); // 预分配对应大小的vector空间 std::vector<uint8_t> result(buf_size); // 直接将序列化数据写入vector底层缓冲区 if (msg.SerializeToArray(result.data(), static_cast<int>(buf_size))) { return result; } // 序列化失败返回空vector,可根据业务需求改为抛出异常 return {}; }
使用示例
// 你的自定义Protobuf消息对象 YourCustomMsg msg; msg.set_user_id(1001); msg.set_username("test_user"); // 直接获取返回的std::vector<uint8_t>序列化结果 std::vector<uint8_t> serialized_buf = serialize_protobuf(msg);
注意事项
- 本实现适用于Protobuf 3及以上版本,若使用Protobuf 2版本,将
ByteSizeLong()替换为ByteSize()即可,注意ByteSize()返回值为int类型,处理大消息时需判断长度溢出风险 - 若需要区分「空消息序列化结果」和「序列化失败」的场景,可以将返回值改为
std::optional<std::vector<uint8_t>>,或在序列化失败时抛出对应业务异常 - 整个过程没有额外的内存拷贝开销,性能和官方
SerializeToArray写入char数组的实现完全一致
内容的提问来源于stack exchange,提问作者Jairo Reyes
相关产品推荐
相关产品推荐

