Как передать тип интерфейса / GUID ссылку на метод автоматизации в Delphi - PullRequest
1 голос
/ 10 мая 2010

В Delphi вы можете передавать ссылки на классы, чтобы сравнивать типы объектов и создавать их экземпляры. Можете ли вы сделать то же самое, передавая ссылки на интерфейс на сервер автоматизации COM?

Например, вы можете определить метод, принимающий параметр GUID, с помощью редактора библиотеки типов:

function ChildNodesOfType(NodeType: TGUID): IMBNode; safecall;

В этой функции я хотел бы вернуть типы автоматизации, которые поддерживают интерфейс, указанный в NodeType, например,

if Supports(SomeNode, NodeType) then
      result := SomeNode;

Но вызов Supports всегда терпит неудачу, я пытался передать Guids, определенный в библиотеке типов, но ни один из различных типов (Ixxx, Class_xxxx, IId_Ixxxx), похоже, не работает.

1 Ответ

4 голосов
/ 10 мая 2010

Блок SysUtils поставляется как минимум с пятью перегрузками Supports, и все они принимают значение TGUID для своих вторых параметров.

Вы действительно можете передавать типы интерфейсов в качестве параметров, но на самом деле они просто GUID. То есть, когда функция ожидает аргумент TGUID, вы можете передать ему идентификатор типа интерфейса, такой как IMBNode или IUnknown. Однако, чтобы это работало, тип интерфейса должен включать GUID в свое объявление, например:

type
  IMBNode = interface
    ['{GUID-goes-here}']
    // methods and properties
  end;

Когда первый параметр Supports является ссылкой на интерфейс, функция вызывает свой метод QueryInterface. Если он возвращает S_OK, то Supports возвращает true; в противном случае возвращается false. Когда первый параметр является ссылкой на объект, он сначала вызывает метод GetInterface объекта, чтобы получить его интерфейс IUnknown, и вызывает Supports для этого, как и прежде. Если это не работает таким образом, то возвращается к запросу запрашиваемого интерфейса непосредственно из GetInterface. Если вы правильно реализовали QueryInterface для своего объекта или использовали реализацию по умолчанию из TInterfacedObject, то все должно работать нормально.

Если Supports никогда не вернет для вас значение true, вам следует пересмотреть некоторые предположения. Вы уверены , что ваш узел действительно поддерживает запрашиваемый интерфейс? Убедитесь, что объявление класса включает этот интерфейс. Убедитесь, что QueryInterface реализован правильно. И убедитесь, что SomeNode действительно ссылается на узел, который вы ожидаете.

...