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

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

6
задан Brian Frost 24 June 2010 в 06:11
поделиться

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));
9
ответ дан 9 December 2019 в 20:39
поделиться

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

3
ответ дан 9 December 2019 в 20:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: