protobuf C++ 利用反射获取消息内容_error: since 鈥榲irtual const reflection* google::pr-程序员宅基地

技术标签: C-C++基础  

protobuf经常会被大家使用,下面演示一下protobuf反射的使用。

protobuf的消息都继承了  google::protobuf::Message 这个父类。

然后可以通过这两个函数来获取消息字段的相关信息,可以看注释

下面演示一下,打印一个消息的全部字段信息。当然你可以利用这个来进行更加贴合自己需求的工作。

对了注意一下:不同版本的protobuf字段类型可能会有差异,大家可以自己比对源码的类型,有些类型可能是废弃的。

void PrintProtoMsg(const google::protobuf::Message& message)
{
    const google::protobuf::Descriptor *des = message.GetDescriptor();
    const google::protobuf::Reflection *ref = message.GetReflection();
    int fieldCount = des->field_count();
    for (int i = 0; i < fieldCount; i++)
    {
        ///< get field with index i
        const google::protobuf::FieldDescriptor *field = des->field(i);
        switch (field->type())
        {
        case google::protobuf::FieldDescriptor::Type::TYPE_INT32:
        case google::protobuf::FieldDescriptor::Type::TYPE_SINT32:
        case google::protobuf::FieldDescriptor::Type::TYPE_SFIXED32:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    int32_t data = ref->GetRepeatedInt32(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                int32_t data = ref->GetInt32(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_INT64:
        case google::protobuf::FieldDescriptor::Type::TYPE_SINT64:
        case google::protobuf::FieldDescriptor::Type::TYPE_SFIXED64:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    int64_t data = ref->GetRepeatedInt64(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                int64_t data = ref->GetInt64(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_UINT32:
        case google::protobuf::FieldDescriptor::Type::TYPE_FIXED32:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    uint32_t data = ref->GetRepeatedUInt32(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                uint32_t data = ref->GetUInt32(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_UINT64:
        case google::protobuf::FieldDescriptor::Type::TYPE_FIXED64:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    uint32_t data = ref->GetRepeatedUInt64(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                uint32_t data = ref->GetUInt64(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_DOUBLE:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    double data = ref->GetRepeatedDouble(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                double data = ref->GetDouble(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_FLOAT:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    float data = ref->GetRepeatedFloat(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                float data = ref->GetFloat(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_BOOL:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    bool data = ref->GetRepeatedBool(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                bool data = ref->GetBool(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_ENUM:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    const google::protobuf::EnumValueDescriptor *data = ref->GetRepeatedEnum(message, field, j);
                    std::cout << data << "," ;
                }
            }
            else
            {
                const google::protobuf::EnumValueDescriptor *data = ref->GetEnum(message, field);
                std::cout << data->number() << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_STRING:
        case google::protobuf::FieldDescriptor::Type::TYPE_BYTES:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    std::cout << data << "," ;
                }
            }
            else
            {
                std::string data = ref->GetString(message, field);
                std::cout << data << "," ;
            }
        }
        break;
        case google::protobuf::FieldDescriptor::Type::TYPE_MESSAGE:
        {
            if (field->is_repeated())
            {
                int count = ref->FieldSize(message, field);
                for (int j = 0; j < count; j++)
                {
                    const google::protobuf::Message &innerMsg = ref->GetRepeatedMessage(message, field, j);
                    PrintProtoMsg(innerMsg);
                }
            }
            else
            {
                const google::protobuf::Message &innerMsg = ref->GetMessage(message, field);
                PrintProtoMsg(innerMsg);
            }
        }
        break;
        default:
            break;
        }
    }
}

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/veghlreywg/article/details/108866392

智能推荐

for语句循环-程序员宅基地

文章浏览阅读868次,点赞18次,收藏18次。for语句,也称为for循环,是编程语言中的一种控制流程结构,它包含三个基本部分:初始化表达式、条件表达式和后续表达式。初始化表达式:在循环开始之前执行,通常用于初始化循环控制变量。条件表达式:在每次循环开始之前进行判断,如果条件为真,则执行循环体;否则,退出循环。后续表达式:在每次循环结束后执行,通常用于更新循环控制变量的值。初始化:在循环开始之前执行,通常用于初始化循环控制变量。条件:在每次循环开始之前进行判断,如果条件为真,则执行循环体;否则,退出循环。更新。

win10开启关闭防火墙以及报错处理和其他段ip无法连接本机远程桌面-程序员宅基地

文章浏览阅读329次,点赞4次,收藏8次。面试前的“练手”还是很重要的,所以开始面试之前一定要准备好啊,不然也是耽搁面试官和自己的时间。我自己是刷了不少面试题的,所以在面试过程中才能够做到心中有数,基本上会清楚面试过程中会问到哪些知识点,高频题又有哪些,所以刷题是面试前期准备过程中非常重要的一点。《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!**

UnicodeDecodeError: ‘utf-8‘ codec can‘t decode byte 0xc4 in position 0: invalid continuation byte_smtplib.smtp_ssl()报错unicodedecodeerror: 'utf-8' co-程序员宅基地

文章浏览阅读242次,点赞9次,收藏3次。UnicodeDecodeError_smtplib.smtp_ssl()报错unicodedecodeerror: 'utf-8' codec can't decode byte 0x

Linux内核学习路线 有入门到深入,10天用Flutter撸了个高仿携程App-程序员宅基地

文章浏览阅读910次,点赞13次,收藏15次。本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。学习驱动,免不了要学习一些硬件的协议和资料,研究哪个就找到相应的硬件文档,把硬件的工作原理搞明白。7. 补充一点经验。6. 现在Linux相关的工作,多集中在一些嵌入式开发领域,arm,mips等,要学习以下这些体系架构的的资料,了解CPU的设计和工作方式。

Java十年 十大组织 写在2005-程序员宅基地

文章浏览阅读92次。摘自《程序员》Sun:因为Java而永被荣光文/孟岩Sun是1980年代初期由斯坦福大学三位年轻学生创立的公司。与一般人的印象不同,“SUN”的本意并不是企图剽窃天上那颗温暖的恒星的威名,而是“斯坦福大学网络...

vue 中如何利用 keep-alive 标签实现某个组件缓存功能?_keep-alive 存储一个组件-程序员宅基地

文章浏览阅读942次。当我们切换组件时,组件的状态被缓存起来,而不是被销毁。这样,在切换回已缓存的组件时,组件的状态将保持不变,提高了性能和用户体验。是Vue提供的内置组件,用于缓存动态组件,可以有效地提高组件的性能,避免重复渲染和销毁。因此,如果你希望缓存某个组件,记得为该组件设置。标签来缓存某个组件,你需要将需要缓存的组件包裹在。属性,这个属性的值为当前需要渲染的组件的名称。在上述示例中,我们有两个组件。属性将被用作缓存的唯一标识。以下是一个示例,演示如何使用。标签来实现组件的缓存功能。标签中,并为该组件设置一个。_keep-alive 存储一个组件

随便推点

【Java基础知识 8】String、StringBuilder、StringBuffer详解-程序员宅基地

文章浏览阅读877次,点赞8次,收藏19次。从上面的代码就可以看出“+”连接字符串的底层,实际上就是StringBuilder对象通过append,再调用toString完成的。

【Python学习篇】Python基础入门学习——你好Python(一)-程序员宅基地

文章浏览阅读639次,点赞25次,收藏26次。首先,不管Python,我们先明白,什么是编程语言语言:进行沟通交流的表达方式人类翻译官无法沟通,那要怎么做才能和计算机交流呢?以Python为例。

南开大学2021年题库考试,南开大学python编程基础-程序员宅基地

文章浏览阅读354次,点赞9次,收藏9次。大家好,小编来为大家解答以下问题,南开大学本科生入学考试试题,南开大学期末考试题题库,今天让我们一起来看看吧!随机储存器,是暂时储存数据和指令的计算机硬件设备,其中储存的数据会在关机或计算机出现异常时自动清除.破坏计算机功能或数据的,能够影响计算机正常使用并且能够自我复制的一组程序或指令。具有记忆功能,能储存数据,指令,程序,运算结果的设备.

【运维面试】秘不外宣的运维项目技术面试准备方法一-程序员宅基地

文章浏览阅读274次,点赞3次,收藏5次。IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?5、LVS、Nginx、HAproxy有什么区别?9、讲述一下Tomcat8005、8009、8080三个端口的含义?7、Tomcat和Resin有什么区别,工作中你怎么选择?3、现在给你三百台服务器,你怎么对他们进行管理?

《算法设计与分析》期末不挂科_算法设计与分析挂科率高吗-程序员宅基地

文章浏览阅读620次,点赞8次,收藏13次。算法:指在解决问题时,按照某种机械步骤一定可以得到问题结果的处理过程。通俗讲,算法就是解决问题的方法或过程。特征1.输入:有零个或多个外部量作为算法的输入。2.输出:算法产生至少一个量或作为输出3.确定性:组成算法的每条指令是清晰的,无歧义的4.有限性 :算法中每条指令的执行次数有限,执行每条指令的时间也有限5.可行性1、执行算法所耗费的时间。2、执行算法所耗费的存储空间,其中主要考虑辅助存储空间。3、算法应易于理解,易于编码,易于调试等。定义:一个直接或间接调用自身的算法。

数据的黄金时代:如何利用fptree算法python开拓数据分析的新领域-程序员宅基地

文章浏览阅读280次,点赞3次,收藏8次。数据的黄金时代:如何利用fptree算法python开拓数据分析的新领域的主要优势在于其强大的算法支持和灵活的数据处理能力。通过使用数据的黄金时代:如何利用fptree算法python开拓数据分析的新领域,用户可以更好地理解数据,从中获取更多价值,并在竞争激烈的市场中脱颖而出。走在数据分析的前沿,开创属于自己的数据黄金时代。数据的黄金时代:如何利用fptree算法python开拓数据分析的新领域是一款基于FPTree算法开发的数据分析应用软件,旨在帮助用户更好地挖掘和分析数据,发现其中的规律和价值。