可以在Delphi中使用Enhanced RTTI获取/设置类级别成员吗?

时间:2013-10-21 12:59:47

标签: delphi oop reflection delphi-xe2 rtti

前言,我似乎没有说清楚。我想枚举,读取和设置给定class var变量的所有TClass或类属性。 找到TClass没有问题 - 它被传递了。 通过给定属性的存在进行过滤没有问题。 问题是RTTI只是错过了枚举类字段而不是实例字段的方法。


我想创建一个声明性DLL加载器。由于DLL在Windows中是进程全局的(您无法加载相同的DLL两次),因此它对应于类级别的字段或属性,而不是即时级别的字段。

所以我想像LoadDLL(filename:string; funtions: TClass)这样的东西,并使用属性来指定要获取的入口点。

然后我遇到了墙:虽然Delphi中有TRttiClassRefType - 但是只能通过给定的实例或其他方式得到它: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. 创建类实例只是为了保存静态指针,在调用时会是一个额外的间接层,并且是一个可以跟踪的冗余实体。

0 个答案:

没有答案