zoukankan      html  css  js  c++  java
  • protobuf的反射机制

    反射机制

    java在运行状态时,能够知道任意类的所有属性和方法,都能够调用任意对象的任意方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    C++本身没有反射机制。protobuf通过proto文件生成相应的messageserviceprotobuf也通过proto文件提供反射机制,程序在运行时可以通过proto获取任意message和任意service的属性和方法,也可以在运行时调用message的属性和方法。

    获取messageservice的属性和方法

    protobuf通过Descriptor获取任意messageservice的属性和方法,Descriptor主要包括了以下集中类型:

     

    FileDescriptor   获取proto文件中的DescriptorServiceDescriptor

    Descriptor      获取类message属性和方法,包括FieldDescriptor  EnumDescriptor

    FieldDescriptor   获取message中各个字段的类型、标签、名称等

    EnumDescriptor   获取Enum中的各个字段名称、值等

    ServiceDescriptor 获取service中的MethodDescriptor

    MethodDescriptor 获取各个rpc中的requestresponse、名称等

     

    当我们获得proto文件的FileDescriptor时,我们就可以获得所有的serviceDescriptorserviceServiceDescriptor,进而获取其相应的字段或rpc。也就是说,如果能获取到proto文件的FileDescriptor,就能所有的proto文件中的所有内容。

    那么如何获取proto文件的FileDescriptor呢?protobuf对应以下两种不同的情况提供了相应的办法

    1、 使用protocproto文件并生成相应的.h.cpp文件。

    这中情况下protobuf已经解析好proto文件,并将所有的Descriptor放在DescriptorPool中了。,可以根据proto的文件名,通过DescriptorPool获取到相应的FileDescriptor,例如,现有test.proto文件,那么可以通过DescriptorPool::generated_pool()获取到其FileDescriptor。其实,对于任意的messageservice,也都可以根据其名称,通过DescriptorPool获取相应的DescriptorServiceDescriptor。例如:

    2、 只有proto文件,不使用protoc

    这种情况需要去手动解析proto文件,然后再获取FileDescriptor。还好protobuf提供了相应的解析器compiler,通过compiler可以很方便得获取proto文件的FileDescriptor,具体如下:

     

    调用message的属性和方法

    想要调用message的属性和方法,就得先获取相应的message对象。protobufmessage对象都是放在MessageFactory中的,可以通过Descriptor,具体如下:

     

    有了message对象,并不能直接调用其对象和方法,因为所有的message对象都是Message*类型的,但不同的message对象的属性和方法是不一样的,在这里,Message*只是指向相应的message大小的地址空间,并不知道对应的message中到底有哪些属性和方法。

    protobuf是通过Reflection调用message的属性和方法的。message中的方法只有对各个属性的getset,而调用message的属性其实也就是调用属性的get。调用message的某一个属性的get,就需要该属性的Descriptor,通过Reflection获取message获取相应的值;调用message某一属性的set,也需要该属性的Descriptor,通过Reflection将相应的值写入到message相应的属性。例如:

     

    反射机制的应用

    有了反射机制,可以写很多工具,比如:基于pb的自动化测试工具、pbjsonxml的工具、pb直接写到数据库的工具等。反射只是一种机制,有什么样的应用场景需要你的想象力!

  • 相关阅读:
    cuda npp库旋转图片
    Xml序列化 详解
    jsonp简介
    在centos7下安装.net core
    安装vs2017后造成无法打开xproj项目无法打开
    SqlServer 语法
    js自定义事件
    HttpWebResponse 解压gzip、deflate压缩
    centos7 安装.net core的方法
    帮助类-从tfs获取数据
  • 原文地址:https://www.cnblogs.com/swey/p/4733638.html
Copyright © 2011-2022 走看看