在Delphi使用增强RTTI一个可以获取/设置类级别的成员?(Can one get/set cl

2019-10-18 19:50发布

前言,看来我没有说清楚。 我想一一列举,读取和设置,所有class var给定的或类属性TClass变量。 没有找到TClass没有问题 - 它被传递。 存在由给定属性的存在下,在过滤没有问题。 目前的问题是,RTTI只是错过枚举类的字段,而不是实例字段的方式。


我想作一个声明DLL加载。 由于DLL是进程全局的窗口(您不能加载同一个DLL的两倍),它对应于类级别字段或属性,而不是即时的水平的。

因此,我认为像LoadDLL(filename:string; funtions: TClass)和使用属性来指定入口点去取。

然后我碰到墙上:虽然有TRttiClassRefType - :在Delphi中一个就是无法通过给定的实例或任何得到它TRTTIContext.GetType(Class)返回上下文的情况下,而不是元类型。

枚举所有的元类型,直到需要一个名字得到的是...难看。 和脆弱。 和缓慢的。 虽然它似乎是唯一包含真正的代码片段TRttiClassRefType ,我可以找到。

所以 - 是有办法,我可以获取和设置类级别的变量或属性,找到他们,一些自定义属性被爱慕?

下面的测试程序只能找到IV和IP,并跳过CV和CP ...

program Project19;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, RTTI;

type
  DLL_Info = class (TCustomAttribute) end;

  {$M+} {$RTTI EXPLICIT FIELDS ([vcPublic]) PROPERTIES ([vcPublic])}
  DLL_Functions = class
     public
       [DLL_Info] var IV: pointer;  // type is just stub
       [DLL_Info] class var CV: pointer;
       [DLL_Info] property IP: pointer read IV;
       [DLL_Info] class property CP: pointer read CV;
  end;
  {$M-}

var df: DLL_Functions;

procedure SetDLLFunctions;
var
  LContext: TRttiContext;
  LType: TRttiType;
  LVar:  TRttiField;
  LProp: TRttiProperty;
  LAttr: TCustomAttribute;

  DLL_fn_Entry, DLL_fn_Optional: boolean;
  DLL_fn_Name: string;
  fn_ptr: Pointer;
begin

  LContext := TRttiContext.Create;
  try
    LType := LContext.GetType(DLL_Functions);
    for LVar in LType.GetFields do begin
        Writeln(Lvar.Name);
    end;
    for LProp in LType.GetProperties do begin
        Writeln(LProp.Name);
    end;
  finally
    LContext.Free;
  end;
end;

begin
  try
   df := DLL_Functions.Create;

   df.IV := @SetDLLFunctions; // imitating DLL quering by GetProcAddress
   df.CV := @SetDLLFunctions;

   SetDLLFunctions;

   df.Destroy;

   ReadLn;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

一些可能的解决方法:

  1. 使用record争取入口点需要经过两个指针:记录本身和TypeInfo 。 这是多余的,并有可能获得语无伦次。

  2. 创建类的实例只是为了保持静态指针将打电话时,一个间接额外的水平,将是一个多余的实体来跟踪。

文章来源: Can one get/set class-level members using Enhanced RTTI in Delphi?