Delphi и COM


         

Сервер без библиотеки типов


Такой сервер, если он не реализует интерфейс IMarshall, может работать лишь в одной «комнате» с клиентом, поэтому его следует использовать только для In-Process-серверов с потоковой моделью, идентичной клиенту.

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

unit Unit1; interface uses   Windows, ActiveX, Classes, ComObj; type   TTest = class(TComObject, ITest)   protected   end; const   Class_Test: TGUID = '{1302FB00-703F-11D4-84DD-825B45DBA617}'; implementation uses ComServ; initialization   TComObjectFactory.Create(ComServer, TTest, Class_Test,     'Test', '', ciMultiInstance, tmApartment); end.

Внимание! COM-сервер, который может использоваться различными клиентами (а не только в рамках конкретного проекта, в котором спецификации клиентов жестко заданы), не рекомендуется создавать без поддержки маршалинга данных, поскольку в этом случае невозможно обеспечить гарантированное нахождение его в одной «комнате» с клиентом. Если вы все же делаете такой сервер, в документации на него необходимо отразить требуемые спецификации клиента.

 

Рассмотрим сгенерированный код подробнее. Особый интерес представляет секция Initialization. В ней создается экземпляр «фабрики объектов» — COM-сервера, реализующего интерфейс IClassFactory2. К нему COM будет обращаться для создания экземпляра объекта Test. VCL автоматически выполняет всю рутинную работу по взаимодействию с COM.

Для реализации сервера требуется написать интерфейсный модуль с описанием реализуемого интерфейса. Кроме того, вынесем в него описание константы Class_Test и добавим его в строку uses модуля Unit1:

unit TestInterface; interface const   Class_Test: TGUID = '{1302FB00-703F-11D4-84DD-825B45DBA617}'; type   ITest = interface   ['{1C986802-6D6D-11D4-84DD-996A491CE716}']     procedure ShowIt(S: String);   end; implementation end.

Этот модуль содержит всю необходимую информацию для работы сервера и должен использоваться при компиляции клиента.

Дополним код COM-объекта реализацией методов реализуемого интерфейса:

unit Unit1; interface uses   Windows, ActiveX, Classes, ComObj, TestInterface; type   TTest = class(TComObject, ITest)   protected     procedure ShowIt(S: String);   end; implementation uses ComServ; { TTest } procedure TTest.ShowIt(S: String); begin   MessageBox(0, PChar(S), NIL, 0); end; initialization   TComObjectFactory.Create(ComServer, TTest, Class_Test,     'Test', '', ciMultiInstance, tmApartment); end.

Откомпилировав проект, мы получим файл Project1.dll.

Последним шагом является регистрация COM-сервера.

Введем в командной строке «regsvr32 project1.dll».

Если все было проделано правильно, на экране должно появиться сообщение об успешной регистрации: «DllRegisterServer in Project1.dll succeeded».

Теперь можно приступать к написанию клиента. Для этого создадим новый проект, добавим в модуль с его главной формой строку uses TestInterface и напишем следующий код:

uses TestInterface, ComObj; procedure TForm1.Button1Click(Sender: TObject); var   Test: ITest; begin   Test := CreateComObject(Class_Test) as ITest;   Test.ShowIt('Hi'); end;

Как видно из этого примера, создание и использование COM-сервера не сложнее, чем работа с обычными классами Delphi. Сервер без библиотеки типов является хорошим выбором для реализации COM-серверов, используемых внутри проекта, поскольку для его работы нужен интерфейсный модуль. При передаче сервера другим разработчикам вам придется передать им этот модуль и при необходимости перевести его на другой язык (например, С).



Содержание раздела