ptotothreads 源码_深入 ProtoBuf - 序列化源码解析

本文深入解析了 ProtoBuf 序列化、反序列化的源码,介绍了如何从代码层面理解 ProtoBuf 对数据的编码和解码过程。通过分析 `SerializeToString` 函数,展示了 ProtoBuf 如何通过 Varint 编码实现消息序列化,并详细讲解了不同字段类型的编码细节,如 int32、int64、bool、enum、fixed32/fixed64、sfixed32/sfixed64 以及长度限定字段的序列化方式。
摘要由CSDN通过智能技术生成

在上一篇 深入 ProtoBuf - 编码 中,我们详细解析了 ProtoBuf 的编码原理。

有了这个知识储备,我们就可以深入 ProtoBuf 序列化、反序列化的源码,从代码的层面理解 ProtoBuf 具体是如何实现对数据的编码(序列化)和解码(反序列化)的。

我们重新复习一下, ProtoBuf 的序列化使用过程:

定义 .proto 文件

protoc 编译器编译 .proto 文件生成一系列接口代码

调用生成的接口实现对 .proto 定义的字段的读取以及 message 对象的序列化、反序列化方法

具体调用代码如下:

Example1 example1;

example1.set_int32val(val);

example1.set_stringval("hello,world");

example1.SerializeToString(&output);

调用 SerializeToString 函数将 example1 对象序列化(编码)成字符串。我们的目的就是了解 SerializeToString 函数里到底发生了什么,是怎么一步一步得到最终的序列化结果的。

注意:并非编码成字符串数据,string 只是作为编码结果的容器

我们在 .proto 文件中定义的 message 在最终生成的对应语言的代码中,例如在 C++ (xxxx.pb.h、xxxx.pb.cpp) 中每一个在 .proto 文件中定义的 message 字段都会在代码中构造成一个类,且这些 message 消息类继承于 ::google::protobuf::Message,而 ::google::protobuf::Message 继承于一个更为轻量的 MessageLite 类。其相关的类图如下所示:

protobuf-class-analysis.png

而我们经常调用的序列化函数 SerializeToString 并定义在基类 MessageLite 中。

编码

当某个 Message 调用 SerializeToString 时,经过一层层调用最终会调用底层的关键编码函数 WriteVarint32ToArray 或 WriteVarint64ToArray,整个过程如下图所示:

ProtoBuf 序列化_反序列化时序图.png

WriteVarint32ToArray 函数可在源码目录下的 google.protobuf.io 包下的 coded_stream.h 中找到。在上一篇 深入 ProtoBuf - 编码 中我们解析了 Va

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值