使用Delphi RTTI获取接口的字符串名称

6

我已经证明可以使用Delphi 2010从接口的GUID获取其名称(例如,IMyInterface转换为字符串“IMyInterface”)。我想在Delphi 7中实现这一点(以确保兼容性)。这是否可行?或者存在基本的编译器限制。

2个回答

10

是的,你可以获取它,以下展示了如何使用IExample类型获取名称。 旧版Delphi 7 RTTI是通过TypInfo单元实现的。

program Project6;
{$APPTYPE CONSOLE}
uses
  SysUtils,TypInfo;

type
  IExample = interface
    ['{4902F666-F3FC-4999-BD8C-F226851201D6}']
    procedure blah;
  end;


begin
  Writeln(GetTypeName(TypeInfo(IExample)));
  readln
end.

刚注意到你说你想从GUID获取它而不仅仅是类型。这将需要一个GUID到类型的注册表。在Delphi 7中,RTTI可以用来获取类型。

以下代码将返回IExample的GUID。

Writeln(GUIDToString(GetTypeData(TypeInfo(IExample)).Guid));

以下是一个示例注册表,将接口的TypeInfo()映射到它的GUID。 它可以进行优化,但我这样做是为了阐述概念。

unit Unit11;

interface
uses
  TypInfo,SysUtils, Contnrs;

type

  TGuidMap = class(TObject)
    Guid : TGUID;
    TypeInfo : PTypeInfo;
  end;

procedure RegisterInterface(InterfaceType : PTypeInfo);

function GetInterfaceType(Guid : TGUID) : PTypeInfo;

implementation
var
  GuidMapList : TObjectList;

procedure RegisterInterface(InterfaceType : PTypeInfo);
var
 Map : TGuidMap;
begin
  Map := TGuidMap.Create;
  Map.TypeInfo := InterfaceType;
  Map.Guid := GetTypeData(InterfaceType).Guid;
  GuidMapList.Add(Map);
end;

function GetInterfaceType(Guid : TGUID) : PTypeInfo;
var
 I : Integer;
begin
 result := nil;
 for I := 0 to GuidMapList.Count - 1 do
 begin
   if IsEqualGUID(TGuidMap(GuidMapList.Items[I]).Guid,Guid) then
   begin
     result := TGuidMap(GuidMapList.Items[I]).TypeInfo;
     break;
   end;
 end;
end;

Initialization
 GuidMapList := TObjectList.Create(true);
finalization
 GuidMapList.Free;
end.

要将项目添加到注册表中,您需要调用以下函数:

   RegisterInterface(TypeInfo(IExample));

3
在Delphi 7中,您应该构建自己的GUID到RTTI(或名称)的映射。与Delphi 2010不同,没有RTTI上下文可用。我广泛使用RIIT,并通常在单元初始化部分的某个中心位置“注册”所有有趣的类型,并从那里基于typeinfo指针查找所有类型。这适用于D7、D2007和D2010(但如果需要创建它,则需要更多的工作)。此外,您可能会忘记注册某个类型,并想知道为什么无法找到某些东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接