Понедельник, 29.04.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нашли свой исходник?
Всего ответов: 94
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Система » CORBA и COM

Создание модулей расширения с использованием технологии COM

Начало

Для создания модулей расширения в среде Borland Delphi на сегодняшний день применяются 3 основные технологии:

  • DLL
  • COM
  • Packages

Недостатком технологии DLL является сложность разработки прикладного программного интерфейса. Недостатком при использовании Packages является жесткая привязка к Delphi и C++ Builder, что является крайне не желательным при сегодняшней распространенности других средств разработки, например: Microsoft Visual Studio.

Таким образом, технология COM предоставляет программисту возможность не привязываться к конкретному продукту для разработки ПО.

Приступим

Для демонстрации технологии разработки плагинов я придумал довольно простую программу, которая будет производить различные операции над двумя вещественными числами.

Шаг 1

Для начала нам необходимо определится, какие функции будет выполнять плагин. Скорее всего, он должен получить 2 числа, выполнить над ними какие-либо операции и возвратить результат в программу. При использовании обычных DLL мы просто сделали бы функцию следующего вида function F(a, b: extended):extended. При использовании COM технологии, в данном примере, всё будет немного сложнее. Нам придется разработать интерфейс для приложения и для плагина.Интерфейсный модуль:

unit PlugIntf;

interface

const
 Class_CalcAPI: TGUID = '{DA18785D-BF58-4C2B-A816-EA1272DDF09E}';

type
 ICalcAPI = interface
 ['{21F0FFFE-9FC7-4C6C-87CE-9BAF44628E46}']
 procedure GetResult(const Result: Extended);
 procedure ShowMessage(const S: WideString);
 end;

 IPluginAPI = interface
 ['{F114301D-075E-4A75-B431-62409F406348}']
 procedure Init();
 procedure Funct(A, B: Extended);
 end;

implementation

end.

Константа Class_CalcAPI будет использоваться нами в плагинах для соединения с приложением и передачи ему результатов.  Реализация интерфейса ICalcAPI является довольно простой, её можно посмотреть в исходном коде приложения. Для автоматического создания такого кода, кроме реализации методов интерфейса, можно поступить следующим образом: создать новый COM объект (вкладка ActiveX)

автоматически будет создан модуль примерно следующего содержания:

unit Unit2;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
 Windows, ActiveX, Classes, ComObj, PlugIntf;

type
 TCalcAPI = class(TComObject, ICalcAPI)
 protected
 procedure GetResult(const Result: Extended);
 procedure ShowMessage(const S: WideString);
 end;

implementation

uses Forms, ComServ, Unit1, SysUtils;

{ TCalcAPI }

procedure TCalcAPI.GetResult(const Result: Extended);
begin
 (Application.MainForm as TForm1).Edit3.Text := FloatToStr(Result);
end;

procedure TCalcAPI.ShowMessage(const S: WideString);
begin
 Form1.Memo1.Lines.Add(S)
end;

initialization
 TComObjectFactory.Create(ComServer, TCalcAPI, Class_CalcAPI,
 'CalcAPI', '', ciMultiInstance, tmSingle);
end.

Следует обратить внимание на последние строки данного модуля. При автоматическом создании данного модуля константа Class_CalcAPI будет находится в данном модуле. Я намеренно перенес данную константу в модуль с интерфейсами т.к. мы будем её использовать в плагинах, а им будет доступен только модуль с заголовками. В принципе на этом реализация программного интерфейса для приложения завершена.

Шаг 2

Для создания плагина нам потребуется всего один файл PlugIntf.pas, т.к. в нем содержится вся необходимая информация.

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

Для создания библиотеки необходимо сделать следующее на странице ActiveX выбрать ActiveX Library, после этого будет автоматически создан необходимый код для нашей библиотеки.

library Project1;

uses
 ComServ;

exports
 DllGetClassObject,
 DllCanUnloadNow,
 DllRegisterServer,
 DllUnregisterServer;

{$R *.RES}

begin
end.

Затем добавим COM Объект который будет реализовывать интерфейс для плагина.

мастер автоматически создаст заготовку для реализации нашего плагина.

unit Unit1;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
 Windows, ActiveX, Classes, ComObj;

type
 TCOMCalcDivPlugin = class(TComObject)
 protected
 end;

const
 Class_COMCalcDivPlugin: TGUID = '{FF85A614-170B-4885-878B-886D321B9E95}';

implementation

uses ComServ;

initialization
 TComObjectFactory.Create(ComServer, TCOMCalcDivPlugin, Class_COMCalcDivPlugin,
 'COMCalcDivPlugin', '', ciMultiInstance, tmApartment);
end.

Далее необходимо подключить к данному модулю модуль PlugIntf.pas и реализовать методы интерфейса IPluginAPI. В итоге у нас получится что-то вроде следующего кода:

unit Unit1;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
 Windows, ActiveX, Classes, ComObj, PlugIntf;

type
 TCOMCalcAddPlugin = class(TComObject, IPluginAPI)
 private
 FCalcAPI: ICalcAPI;
 protected
 procedure Init();
 procedure Funct(A, B: Extended);
 end;

const
 Class_COMCalcAddPlugin: TGUID = '{8AAA1D29-3C8A-438E-9A78-637072EDCC3F}';

implementation

uses ComServ;

{ TCOMCalcAddPlugin }

procedure TCOMCalcAddPlugin.Funct(A, B: Extended);
begin
 FCalcAPI.GetResult(A+B);
end;

procedure TCOMCalcAddPlugin.Init;
begin
 FCalcAPI := CreateComObject(Class_CalcAPI) as ICalcAPI;
 FCalcAPI.ShowMessage('Plugin ADD Init...');
end;

initialization
 TComObjectFactory.Create(ComServer, TCOMCalcAddPlugin, Class_COMCalcAddPlugin,
 'COMCalcAddPlugin', '', ciMultiInstance, tmSingle);
end.

Рекомендую обратить внимание на реализацию метода Init в нем мы подключаемся к уже существующему интерфейсу. Если попытаться вызвать методы данного плагина из другого приложения, то (в зависимости от реализации COM серверов) могут быть 2 варианта:

  1. Плагин запустит приложение COMCalc.exe и будет продолжать работать
  2. Плагин не сможет запустить приложение COMCalc.exe и вылетит с ошибкой.

В моей практике случалось и то и другое.

На этом наш плагин готов к работе осталось только его вызвать.

Шаг 3

Для простоты я создал следующий файл:

[simple]

add={8AAA1D29-3C8A-438E-9A78-637072EDCC3F}

sub={D645945D-E9D7-44DC-A269-0839F9DC118C} 

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

Код для вызова плагина приводится ниже. Ничего особенно сложного я в данном коде не вижу. На мой взгляд данный код не должен нуждаться в комментариях, т.к. он довольно простой.

var

 ini: TIniFile;

 PlugGUID: String;

 PlugName: String;

 Plugin: IPluginAPI;

begin

if ListBox1.ItemIndex > -1 then

 begin

 ini := TIniFile.Create(ExtractFilePath(Application.ExeName)+'plugins.ini');

 PlugName := ListBox1.Items[ListBox1.ItemIndex];

 try

 PlugGUID := ini.ReadString('simple',PlugName,'');

 finally

 ini.Free;

 end;

 Plugin := CreateComObject (StringToGUID(PlugGUID)) as IPluginAPI;

 Plugin.Init;

 Plugin.Funct(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text));

 endelse

 ShowMessage('необходимо выбрать плагин')

end;

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

Заключение

Здесь я привожу несколько замечаний по статье:

  • В статье ни разу я не указывал путь к плагинам. При использовании COM технологии можно вообще забыть про пути, т.к. при регистрации библиотеки в системном реестре прописывается путь к ней, а при вызове система сама находит данную библиотеку.
  • Если просто скомпилировать данный пример и запустить, то скорее всего он у вас не будет работать, после компиляции плагинов необходимо их зарегистрировать. Это можно сделать двумя путями
    • В командной строку написать regsvr32 <имя плагина>.dll
    • В меню делфи Run -> Register ActiveX Server
  • Не буду отрицать, что у технологии COM нет недостатков. Например ограниченность типов данных.

Для более подробного знакомства с данной технологией я рекомендую всем книгу «Делфи и технология COM», Питер 2003, Серия Мастер Класс.

Автор - Непряхин Алексей

Получить ссылку на материал

Категория: CORBA и COM | Добавил: Барон (20.12.2011)
Просмотров: 953 | Теги: com | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
ActiveX [10]
CORBA и COM [16]
Kol и MCK [23]
WinAPI [28]
Компоненты [27]
Работа с Bluetooth [4]
Железо [8]
Текст [18]
Разное [98]
Королевство Delphi © 2010-2024
Яндекс цитирования