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

Избегание Использования TInterfacedObject и Интеграция COM в Существующие Классы

Delphi , Технологии , COM и DCOM

Объединение интерфейсов с любым классом (tnx Warfley!)

В недавнем обсуждении на форуме было поднято предложение о возможности добавления COM-интерфейса к любому классу, не наследующему TInterfacedObject. Это обновление позволяет использовать механизм автоматического управления памятью (стиль ARC) и расширяет функциональность разработчиков, работающих с компонентным программированием.

Проблема

До недавнего времени, для добавления COM-интерфейса к классу, необходимо было, чтобы класс наследул TInterfacedObject. Это ограничение не позволяло использовать данный механизм для объектов, которые не могут быть изменены для наследования от TInterfacedObject, например, для третьесторонних библиотек или классов, имеющих сложную иерархию.

Решение

Внедрение обобщенного класса TInterfaced<T> позволяет добавить интерфейс к любому классу, сохраняя при этом возможность использования всех методов и свойств TObject. Это достигается за счет использования обобщений (generics), которые генерируют необходимый код для каждого конкретного класса, к которому добавляется интерфейс.

Пример кода, который реализует данное решение:

Program examplecom;
uses classes;
type
  IInterfaced = interface
  ['{ADEAD83C-06E1-41A5-A40B-C19D06FE8B9F}']
  end;
  TInterfaced<T:class,constructor> = class(T,IInterfaced)
  private
    frefcount:integer;
    FDestroyCount:integer;
  public
    function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;
      out obj) : longint;winapi;
    function _AddRef : longint;winapi;
    function _Release : longint;winapi;
    destructor destroy;override;
    procedure AfterConstruction;override;
    procedure BeforeDestruction;override;
    class function NewInstance : TObject;override;
  end;
  // ... Дальше следует реализация методов QueryInterface, _AddRef, _Release и др.

type
  TInterfacedStringlist = TInterfaced<TStringlist>;
  var
  List:IInterfaced;
  SList:TStringlist;
begin
  List :=TInterfacedStringlist.create;
  with list as TInterfacedStringlist do
  begin
    Add('some text');
    writeln(Text);
  end;
  // ... Код использования объекта с интерфейсом
end.

Альтернативное Решение

Альтернативный подход, предложенный ASerge, заключается в создании обертки для любого объекта, которая предоставляет интерфейс. Этот подход не требует изменения исходного класса и не влечет за собой дублирование кода. Пример такой обертки:

unit uIntfWrapper;
{$mode ObjFPC}{$H+}
interface
function WrapByInterface(SomeObj: TObject; AOwned: Boolean = True): IInterface;
implementation
uses SysUtils, Classes;
type
  TIntfWrapper = class(TInterfacedObject, IInterface)
  strict private
    FObj: TObject;
    FOwned: Boolean;
    function QueryInterface(constref iid: TGuid; out Obj): LongInt; winapi;
  public
    constructor Create(AObj: TObject; AOwned: Boolean = True);
    destructor Destroy; override;
  end;
  // ... Реализация класса TIntfWrapper

function WrapByInterface(SomeObj: TObject; AOwned: Boolean): IInterface;
begin
  Result := TIntfWrapper.Create(SomeObj, AOwned);
end;
end.

Использование обертки:

{$MODE OBJFPC}
{$APPTYPE CONSOLE}
uses SysUtils, Classes, uIntfWrapper;
var
  IList: IInterface;
begin
  IList := WrapByInterface(TStringList.Create);
  with IList as TStringList do
  begin
    Add('some text');
    Writeln(Text);
  end;
  Readln;
end.

Заключение

Оба подхода решают проблему добавления интерфейсов к существующим классам, но выбирать между ними следует, исходя из конкретных требований проекта и предпочтений разработчика. Обобщенный класс TInterfaced<T> предоставляет гибкость и возможность использования всех методов TObject, в то время как обертка TIntfWrapper упрощает процесс и не требует изменений в исходном коде.

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

Объединение интерфейсов с любым классом стало возможным благодаря введению обобщенного класса `TInterfaced`, который позволяет добавить COM-интерфейс к любому объекту, не зависящему от наследования `TInterfacedObject`, что расширяет функциональность д


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

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




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


:: Главная :: COM и DCOM ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-02-19 02:00:49/0.0032951831817627/0