Получение строкового имени интерфейса с помощью Delphi RTTI

Я доказал, что могу получить имя интерфейса из его GUID с помощью Delphi 2010 (например, IMyInterface преобразуется в строку «IMyInterface». Я хотел бы добиться этого в Delphi 7 (для совместимости). Возможно ли это? Или существуют фундаментальные ограничения компилятора.


person Brian Frost    schedule 24.06.2010    source источник


Ответы (2)


Да, вы можете получить его, ниже показано, как вы можете получить имя, используя тип 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 для типов. Для получения типа можно использовать RTTI в Delphi 7.

Следующее приведет к тому, что 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));
person Robert Love    schedule 24.06.2010

В Delphi 7 вы должны создать собственное сопоставление GUID с RTTI (или именем). Здесь нет контекста RTTI, как в Delphi 2010. Я широко использую RIIT и обычно «регистрирую» все интересные типы в разделе инициализации модуля где-то в центре и нахожу все типы оттуда на основе указателя typeinfo. Это работает для D7, D2007 и D2010 (но это больше работы, если вам нужно его создать). Также вы можете забыть зарегистрировать тип и задаться вопросом, почему что-то не может быть найдено.

person Ritsaert Hornstra    schedule 24.06.2010