protobuf 反射使用总结

背景

反射是指可以动态获取任意类的属性和方法以及动态调用任意对象的属性和方法的机制。C++ 本身没有反射机制,但通过 protobuf 可以在运行时获取和修改对象的字段。

反射相关类

①.Descriptor
Descriptor 包含了对 message 的描述,以及其所有字段的描述。
②.FieldDescriptor
FieldDescriptor 包含了对 message 中单个字段的详细描述。
③.Reflection
Reflection 提供了对 message 中单个字段进行动态读写的方法。

使用反射创建 message

①.概述
DescriptorPool 中存储了所有 message 的元信息;
MessageFactory 是一个实例创建工厂,可以根据 message 的描述信息得到其默认实例;
根据类型的默认实例可以创建同类型的 message 对象;
mesaage 的类型名称要带上其 package 名称。

②.示例 message

message DemoMsg
{
   int32 id = 1;
   string name = 2;
}

③.使用反射创建 message

auto getMessageByName = [](const string & msgType){
     auto desc = google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(msgType);
     if (!desc) return shared_ptr<google::protobuf::Message>(nullptr);
     auto instance = google::protobuf::MessageFactory::generated_factory()->GetPrototype(desc);
     if (!instance) return shared_ptr<google::protobuf::Message>(nullptr);
     std::shared_ptr<google::protobuf::Message> msg = std::shared_ptr<google::protobuf::Message>(instance->New());
     return msg;
};
string msgType = "protoTest.DemoMsg";
auto msg = getMessageByName(msgType);
if (msg)  cout << msgType << " 创建成功" << endl;

在这里插入图片描述

使用反射读写字段

①.概述
根据 message 的描述可以得到字段的描述;
使用 message 的反射和字段的描述可以进行字段值的读写。
②.使用反射设置字段值

string msgType = "protoTest.DemoMsg";
auto msg = getMessageByName(msgType);auto desc = msg->GetDescriptor();
auto refl = msg->GetReflection();
auto field = desc->FindFieldByName("name");
refl->SetString(msg.get(), field, "1234");
    
cout << msg->DebugString() << endl;

在这里插入图片描述

③.使用反射读取字段值

if( refl->HasField(*msg, field) )
        cout <<  refl->GetString(*msg, field) << endl;

在这里插入图片描述

使用反射遍历字段

①.概述

使用反射可以在运行时对 message 的所有字段进行遍历。

②.使用反射遍历字段

protoTest::DemoMsg msg;
    
auto desc = msg.GetDescriptor();
auto refl = msg.GetReflection();int size = desc->field_count();
for (int i = 0; i < size; ++i)
{
    auto field = desc->field(i);
    cout << field->name() << " " << field->type_name() << endl;
}

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值