Getting the string name of an interface using Delphi RTTI

南楼画角 提交于 2019-12-06 02:07:48

问题


I have proved that I can get the name of an interface from its GUID using Delphi 2010 (eg IMyInterface converted to the string 'IMyInterface'. I'd like to achieve this in Delphi 7 (for compatibility). Is this possible? Or are there fundamental compiler limitations.


回答1:


Yes you can get it, the following shows using the IExample type how you can get the name. The old Delphi 7 RTTI was done through the TypInfo Unit.

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.

Just noticed you said you wanted to get it from the GUID and not just the type. This would require a registry of GUID to types. The RTTI in Delphi 7 can be used to get the type.

The following will take IExample return the guid.

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

Here is an example registry that would Map TypeInfo() of an Interface to it's GUID. It could be optimized but I did it to illustrate the concept.

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.

To Add an item to the registry you would then call

   RegisterInterface(TypeInfo(IExample));



回答2:


In Delphi 7 you should build your own mapping from GUID to RTTI (or Name). THere is no RTTI context like in Delphi 2010. I use RIIT extensively and usually "register" all interesting types in the initialization section of the unit somewhere central and find all types from there based upon the typeinfo pointer. This works for D7, D2007 and D2010 (but is more work if you need to create it). Also you might forget to register a type and wonder why o why something cannot be found.



来源:https://stackoverflow.com/questions/3107583/getting-the-string-name-of-an-interface-using-delphi-rtti

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!