当前位置:网站首页>protobuf 反射使用总结
protobuf 反射使用总结
2022-08-03 16:05:00 【litanyuan】
背景
反射是指可以动态获取任意类的属性和方法以及动态调用任意对象的属性和方法的机制。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;
}


边栏推荐
猜你喜欢

深度学习GPU最全对比,到底谁才是性价比之王?

Fortinet产品导入AWS AMI操作文档

面了个腾讯35k出来的,他让我见识到什么叫精通MySQL调优

Interpretation of the 2021 Cost of Data Breach Report
![[Deep Learning] Today's bug (August 2)](/img/c5/c4c6d97276bd9997c49ed886aa24cf.png)
[Deep Learning] Today's bug (August 2)

MySQL相关介绍

Introduction to spark learning - 1

如何启动 NFT 集合

使用Make/CMake编译ARM裸机程序(基于HT32F52352 Cortex-M0+)
![leetcode: 899. Ordered Queue [Thinking Question]](/img/e0/5ea1df0d40a166d0be0309b4608e6d.png)
leetcode: 899. Ordered Queue [Thinking Question]
随机推荐
Kubernetes 笔记 / 任务 / 管理集群 / 用 kubeadm 管理集群 / 配置一个 cgroup 驱动
devops-2:Jenkins的使用及Pipeline语法讲解
Small Tools (4) integrated Seata1.5.2 distributed transactions
请问大家,MySQL全量怎么样可以提高性能呢?我这里瓶颈是在Source上,在不增加并行度的情况下,
MySQL相关介绍
CPU个数_核心数_线程数之间的关系
生态剧变,电子签名SaaS模式迎来新突破,网络效应加速到来
【翻译】关于扩容一个百万级别用户系统的六个课程
带你了解什么是 Web3.0
[Unity Getting Started Plan] Basic Concepts (8) - Tile Map TileMap 01
为教育插上数字化的翅膀,网易云信发布「互联网+教育」整体解决方案
攻防世界----bug
MySQL性能优化_小表驱动大表
leetcode: 899. Ordered Queue [Thinking Question]
Kubernetes 笔记 / 目录
TCP 可靠吗?为什么?
《安富莱嵌入式周报》第276期:2022.07.25--2022.07.31
30W 2C(JD6606S + FP6652X2)BOM
Awesome!Coroutines are finally here!Thread is about to be in the past
甲方不让用开源【监控软件】?大不了我自己写一个