Я доказал, что могу получить имя интерфейса из его GUID с помощью Delphi 2010 (например, IMyInterface преобразуется в строку «IMyInterface». Я хотел бы добиться этого в Delphi 7 (для совместимости). Возможно ли это? Или существуют фундаментальные ограничения компилятора.
Получение строкового имени интерфейса с помощью Delphi RTTI
Ответы (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));
В Delphi 7 вы должны создать собственное сопоставление GUID с RTTI (или именем). Здесь нет контекста RTTI, как в Delphi 2010. Я широко использую RIIT и обычно «регистрирую» все интересные типы в разделе инициализации модуля где-то в центре и нахожу все типы оттуда на основе указателя typeinfo. Это работает для D7, D2007 и D2010 (но это больше работы, если вам нужно его создать). Также вы можете забыть зарегистрировать тип и задаться вопросом, почему что-то не может быть найдено.