Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Реализация метода `QueryInterface` в классах, наследующих `TInterfacedObject` в Delphi

Delphi , Программа и Интерфейс , Интерфейс

Реализация метода QueryInterface в классах, наследующих TInterfacedObject в Delphi

Вопрос, заданный пользователем, связан с реализацией метода QueryInterface в классе, который наследует TInterfacedObject в среде разработки Delphi. Метод QueryInterface является частью интерфейса IUnknown, который является базовым для всех COM-объектов. В Delphi IUnknown объявляется следующим образом:

function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

Параметр Obj является параметром вывода без указанного типа. В классе, наследующем TInterfacedObject, необходимо обработать метод QueryInterface, чтобы возвращать объекты, поддерживающие запрошенный интерфейс. Пример реализации:

function TFoo.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
    if IsEqualGUID(IID, IFooBar) then
    begin
        Obj := (TFooBar.Create(Self) as IFooBar);
        Result := S_OK;
    end
    else
        Result := inherited QueryInterface(IID, {out}Obj);
end;

Однако, при попытке присвоить значение параметру Obj, компилятор выдает ошибку, указывая, что оператор не может быть применен к данному типу операнда.

Решение проблемы заключается в том, чтобы привести тип параметра Obj к типу интерфейса, который вы хотите вернуть. Это позволит компилятору правильно интерпретировать присваивание:

IFooBar(Obj) := TFooBar.Create(Self) as IFooBar;

Также стоит отметить, что после создания объекта интерфейса необходимо вызвать метод _AddRef, чтобы увеличить счетчик ссылок на объект. В данном случае, если использовать тип Obj как интерфейс IFooBar перед присваиванием, то компилятор автоматически вызовет _AddRef при необходимости.

Стоит помнить, что в COM-объектах важно соблюдать правила управления ресурсами, в том числе правильное управление счетчиками ссылок.

Альтернативный подход

Если задача состоит в том, чтобы возвращать один и тот же объект IUnknown при запросе, можно использовать ключевое слово implements и делегировать новый интерфейс адаптер-классу, созданному в геттере свойства. Однако, это может привести к необходимости кэширования объектов для каждого поддерживаемого интерфейса.

Пример альтернативной реализации

Можно также попробовать следующий подход:

function TFoo.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
    if IsEqualGUID(IID, IFooBar) then
        Result := TFooBar.Create(Self).QueryInterface(IID, Obj)
    else
        Result := inherited QueryInterface(IID, {out}Obj);
end;

В данном случае, вызов QueryInterface на объекте TFooBar автоматически обработает необходимый _AddRef.

Заключение

При реализации метода QueryInterface важно учитывать правила COM, в частности, управление ссылочными счетчиками. Приведенные примеры демонстрируют, как можно правильно обработать вызов метода QueryInterface в классе, наследующем TInterfacedObject, и вернуть интерфейс, поддерживаемый объектом.

Создано по материалам из источника по ссылке.

Метод `QueryInterface` должен быть правильно реализован в классах, наследующих `TInterfacedObject` в Delphi, для корректной работы с интерфейсами COM и управления ссылочными счетчиками.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Интерфейс ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-02-05 14:53:53/0.0037400722503662/0