Вопрос разработчиков, работающих с Delphi, часто связан с необходимостью получения информации об интерфейсах, в частности, о GUID (Globally Unique Identifier) интерфейсов. Это может быть необходимо для отладки, идентификации типов в интерфейсах или для других операций, связанных с работой с объектами.
Проблема
Разработчик хочет получить информацию об интерфейсе, аналогичную той, что отображается в IDE при отладке (например, TMyObject($5864933A) as IMyInterface). В реальных условиях разработчик сталкивается с ситуацией, когда указатель на интерфейс ведет себя некорректно, и ему необходимо получить более подробную информацию об этом интерфейсе.
Исходный код, который разработчик пытается использовать, выглядит следующим образом:
type
IMyInterface = interface
['{ABDA7685-DB67-43C1-947F-4B9535142355}']
end;
TMyObject = class(TInterfacedObject, IMyInterface)
end;
var
T: PTypeInfo;
I: IMyInterface;
begin
I := TMyObject.Create;
T := TypeInfo(I);
// ...
end;
Однако, TypeInfo требует тип, а не экземпляр, поэтому такой подход не работает. Разработчик пытается использовать старый хак от Hallvarda, но в Delphi 10.2 этот метод больше не работает. При вызове функции GetInterfaceIID происходит ошибка доступа.
Решение
Разработчику удалось собрать рабочую программу, включающую необходимые рутины:
program TestInterfaceTypeInfo;
{$APPTYPE CONSOLE}
uses
SysUtils,
TypInfo,
Rtti,
System.Generics.Collections,
Classes;
function InterfaceTypeInfo(const Intf: IInterface): PTypeInfo;
// ... (код функции)
begin
// ...
end;
Программа включает в себя функцию InterfaceTypeInfo, которая возвращает PTypeInfo для переданного интерфейса. Это позволяет получить GUID интерфейса и, используя его, получить дополнительную информацию о типе интерфейса.
var
MyInterface: IInterfaceComponentReference;
Unknown: IUnknown;
Instance: TObject;
IID: TGUID;
T: PTypeInfo;
begin
MyInterface := TComponent.Create(nil);
// ... (продолжение кода)
end.
Запуск программы приведет к выводу информации о GUID интерфейса и типе объекта.
Пример кода
Для полноты картины приведем пример использования функции InterfaceTypeInfo:
T := InterfaceTypeInfo(MyInterface);
if Assigned(T) then
begin
writeln('TypeInfo = ', T.Name, GUIDToString(T.TypeData.GUID));
writeln(Format('%s($%x) as %s', [(MyInterface as TObject).ClassName, NativeInt(MyInterface), T.Name]));
end;
Этот код выведет имя типа, GUID и информацию о текущем экземпляре объекта, реализующего интерфейс.
Заключение
Получение GUID интерфейса в Delphi может быть необходимо для различных задач, связанных с разработкой и отладкой. Использование функции InterfaceTypeInfo позволяет разработчику получать подробную информацию об интерфейсах, что может быть крайне полезно при работе с интерфейсными типами в Object Pascal.
Разработчики в Delphi столкнулись с необходимостью получения GUID интерфейсных типов для отладки и идентификации, используя функцию `InterfaceTypeInfo` для извлечения информации об интерфейсах.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS