ProtoBuf中的反射

同时写Python和C++的程序员,往往会觉得C++写起来很累。(所谓“累守恒定律”: 程序执行时的累 + 程序员写代码时的累 = 恒定的累^_^)

在处理ProtoBuf Message数据时,经常会有这样的需求,根据一个输入的字符串,找到Message中对应属性的取值;或者根据输入的字符串和一个值,设置Message中对应属性的取值。

这种需求放在Python中,往往直接通过getattr/setattr就能一步搞定。但是在C++中,我们不得不借助于ProtoBuf的反射机制。

这里,需要介绍如下几个概念:

google :: protobuf :: Message

Message是protobuf中的基本类型,protobuf中所有自定义对象都继承自Message。

通过Message我们可以获得Message的Descriptor和Reflection。

google :: protobuf :: Descriptor

Descriptor正如其名,是对Message的描述,包括字段个数,所有字段的描述等等。

通过Descriptor,我们可以获得一个字段的FieldDescriptor。

google :: protobuf :: Reflection

Reflection就是具体执行相关反射操作,比如当拿到了Message的FieldDescriptor,就可以通过Reflection来读写这个字段。

google :: protobuf :: FieldDescriptor

FieldDescriptor是用于描述字段的,比如字段的类型、名字、修饰符(repeated/required/optional)等。

code snippet

有了上面的这四大金刚,根据输入的字符串,动态的从Message中获得属性的值,可以用以下这段代码片段搞定:

这里只是示意了获取简单类型的方式,获取Repeated类型可以用Reflection的GetRepeatedInt32函数;而获取嵌套的Message则可以用Reflection的GetMessage函数。

题图:mambeau

授权:CC0协议

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180908G0MVDT00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券