Protobuf Reflection 反射使用

2024-06-22 08:04

本文主要是介绍Protobuf Reflection 反射使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Protobuf Reflection 反射使用

源码地址:https://github.com/Michaelzhouisnotwhite/DemoCXXCode/blob/main/src/protobuf-reflection/main.cpp
首先创建一个proto文件:

syntax = "proto3";// option optimize_for = LITE_RUNTIME; // 不使用MessageLitepackage pb;message Data {uint64 id = 1;string value = 2;
}
message DataList {repeated Data data = 1;int64 uid = 2;
}

NOTE 如何生成pb.c文件不赘述了

如何实现反射:

创建一个动态读取proto的importer

google::protobuf::compiler::DiskSourceTree source_tree{};// proto文件夹
source_tree.MapPath("proto",PROTO_ROOT_PATH);google::protobuf::compiler::Importer importer(&source_tree, nullptr);
const auto* desp = importer.Import("proto/test_msg.proto"); // 从文件夹导入文件

获得proto中的pb.DataList消息

const auto* desp_pool = desp->pool(); // 列出文件中所有描述器
const auto* msg_desp = desp_pool->FindMessageTypeByName("pb.DataList"); // 找到messagegoogle::protobuf::DynamicMessageFactory factory; // 创建工厂
auto* msg = factory.GetPrototype(msg_desp)->New(); // 得到目标message然后创建msg->ParseFromString(data_list_raw_data); // 解析

动态解析所有message中的field

auto parse_msg_field(const google::protobuf::Message* msg, int recurtion_level) -> void {const auto* ref = msg->GetReflection(); // 得到message的反射const auto* desp2 = msg->GetDescriptor(); // 得到message的描述器auto prefix = std::string("  ", recurtion_level);for (int i = 0; i < desp2->field_count(); ++i) {auto field = desp2->field(i);fmt::print("{}", prefix);fmt::print("{}   {}   {}    {}", field->number(), field->type_name(),field->cpp_type_name(), field->name());if (field->message_type()) {// fmt::println("current field is a message type");}switch (field->cpp_type()) {case google::protobuf::FieldDescriptor::CPPTYPE_INT64: {fmt::println("   {}", ref->GetInt64(*msg, field));}break;case google::protobuf::FieldDescriptor::CPPTYPE_STRING: {fmt::println("   {}", ref->GetString(*msg, field));}break;case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: {fmt::println("   {}", ref->GetUInt64(*msg, field));}break;case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {fmt::println("");if (field->is_repeated()) {for (int rid = 0; rid < ref->FieldSize(*msg, field); rid++) {parse_msg_field(&ref->GetRepeatedMessage(*msg, field, rid),recurtion_level + 1);}}}break;default: {fmt::print("{}", prefix);fmt::println("can't parse type: {} {}", field->type_name(), field->name());}break;}}
}

这篇关于Protobuf Reflection 反射使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1083718

相关文章

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

C#下Newtonsoft.Json的具体使用

《C#下Newtonsoft.Json的具体使用》Newtonsoft.Json是一个非常流行的C#JSON序列化和反序列化库,它可以方便地将C#对象转换为JSON格式,或者将JSON数据解析为C#对... 目录安装 Newtonsoft.json基本用法1. 序列化 C# 对象为 JSON2. 反序列化

RabbitMQ 延时队列插件安装与使用示例详解(基于 Delayed Message Plugin)

《RabbitMQ延时队列插件安装与使用示例详解(基于DelayedMessagePlugin)》本文详解RabbitMQ通过安装rabbitmq_delayed_message_exchan... 目录 一、什么是 RabbitMQ 延时队列? 二、安装前准备✅ RabbitMQ 环境要求 三、安装延时队

Python ORM神器之SQLAlchemy基本使用完全指南

《PythonORM神器之SQLAlchemy基本使用完全指南》SQLAlchemy是Python主流ORM框架,通过对象化方式简化数据库操作,支持多数据库,提供引擎、会话、模型等核心组件,实现事务... 目录一、什么是SQLAlchemy?二、安装SQLAlchemy三、核心概念1. Engine(引擎)

Java Stream 并行流简介、使用与注意事项小结

《JavaStream并行流简介、使用与注意事项小结》Java8并行流基于StreamAPI,利用多核CPU提升计算密集型任务效率,但需注意线程安全、顺序不确定及线程池管理,可通过自定义线程池与C... 目录1. 并行流简介​特点:​2. 并行流的简单使用​示例:并行流的基本使用​3. 配合自定义线程池​示

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

使用shardingsphere实现mysql数据库分片方式

《使用shardingsphere实现mysql数据库分片方式》本文介绍如何使用ShardingSphere-JDBC在SpringBoot中实现MySQL水平分库,涵盖分片策略、路由算法及零侵入配置... 目录一、ShardingSphere 简介1.1 对比1.2 核心概念1.3 Sharding-Sp

Java 正则表达式的使用实战案例

《Java正则表达式的使用实战案例》本文详细介绍了Java正则表达式的使用方法,涵盖语法细节、核心类方法、高级特性及实战案例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、正则表达式语法详解1. 基础字符匹配2. 字符类([]定义)3. 量词(控制匹配次数)4. 边

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案