Главная » Delphi » Внутренние серверы COM

0

Внутренний сервер (in process  server)  COM представляет собой  библиотеку DLL, кото рая может  создавать объекты COM, предназначенные для использования в главном приложении. Этот тип сервера COM называется внутренним, потому что он, как и биб лиотека DLL, относится к тому же процессу, что и основное приложение. Внутренний сервер должен экспортировать (предоставлять) четыре стандартные функции:

function DllRegisterServer: HResult; stdcall; function DllUnregisterServer: HResult; stdcall; function DllGetClassObject (const CLSID,

IID: TGUID; var Obj): HResult; stdcall;

function DllCanUnloadNow: HResult; stdcall;

Каждая  из  таких  функций  уже реализована в модуле  ComServ, поэтому  остается лишь убедиться в том, что данные  функции добавлены в раздел exports проекта.

НА ЗАМЕТКУ

Хороший пример применения внутренних серверов COM можно найти в главе 16, “Программирование для оболочки Windows”. Этот пример демонстрирует создание расширений оболочки.

Функция DllRegisterServer()

Функция  DllRegisterServer() вызывается для  регистрации  библиотеки  DLL сервера COM  в системном реестре. Если  просто экспортировать данный метод  из приложения Delphi, как описывалось выше,  то  подпрограммы библиотеки VCL по следовательно опросят все  объекты COM  этого  приложения и зарегистрирует  их  в системном реестре. Для  каждого  класса  COM  при  регистрации сервера COM  в сис темном  реестре создается раздел в следующей ветви:

HKEY_CLASSES_ROOT\CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx}

Здесь  символы x…х заменяют реальный  идентификатор  CLSID  этого   класса COM.  Для внутренних серверов создается также  подраздел InProcServer32. Пара метром по умолчанию в таком  подразделе является полный путь к библиотеке  DLL внутреннего сервера. На рис. 15.1 показан пример сервера COM, зарегистрированно го в системном реестре.

Рис. 15.1. Сервер COM в окне редактора системного реестра

Функция DllUnregsterServer()

Данная функция предназначена для отмены действий, выполненных функцией DllRegisterServer(). При  вызове  эта функция удаляет все разделы, подразделы и параметры, созданные функцией DllRegisterServer() в системном реестре.

Функция DllGetClassObject()

Функция  DllGetClassObject() вызывается механизмом COM для получения фаб рики  конкретного класса COM. Параметр CLSID этого  метода — не что иное, как иден тификатор CLSID типа  создаваемого класса  COM.  Параметр IID содержит значение идентификатора интерфейса (IID) — указателя  на экземпляр, который необходимо по лучить  для объекта фабрики классов  (обычно здесь  передается идентификатор интер фейса IClassFactory). При корректном завершении функции параметр Obj содержит указатель  на интерфейс фабрики классов, обозначенный параметром IID и способный создавать объекты COM с типом класса, определенным параметром CLSID.

Функция DllCanUnloadNow()

Данная функция вызывается механизмом COM для определения возможности вы грузки из памяти библиотеки DLL данного сервера COM. Если внутри  этой  библиоте ки  DLL  существуют  указатели  на  какой либо  объект COM,  то  функция  возвращает значение S_FALSE, указывающее на то,  что  библиотеку выгрузить нельзя. Если же в библиотеке DLL не используется в данный момент ни один из объектов COM, то функция возвращает значение S_TRUE.

CОВЕТ

Даже если все ссылки на объекты COM внутреннего сервера уже освобождены, иногда не нужно вызывать функцию DllCanUnloadNow() для инициирования процесса вы- грузки из памяти библиотеки DLL внутреннего сервера. Если желательно гарантиро- ванно выгрузить все неиспользуемые библиотеки DLL сервера COM из памяти, вызо- вите функцию API COM CoFreeUnusedLibraries(), которая определена в модуле ActiveX следующим образом:

procedure CoFreeUnusedLibraries; stdcall;

Создание экземпляра внутреннего сервера COM

Для создания экземпляра сервера COM  в среде  Delphi необходимо использовать функцию CreateComObject(), определенную в модуле ComObj следующим образом:

function CreateComObject(const ClassID: TGUID): IUnknown;

Параметр ClassID содержит идентификатор CLSID, который определяет тип  соз даваемого объекта COM.  Значение, возвращаемое этой  функцией, —  интерфейс IUn- known требуемого объекта COM. Если объект COM не может  быть создан,  то возникает исключение.

Функция   CreateComObject() инкапсулирует  функцию  API  COM  CoCreateIn- stance(). Внутри  функции CoCreateInstance(), для получения интерфейса IClassFactory заданного объекта COM,  вызывается функция API COM  CoGetClas- sObject(). Функция  CoCreateInstance() выполняет этот вызов,  осуществив поиск  в системном реестре параметра InProcServer32 заданного класса COM для определения пути к библиотеке DLL внутреннего сервера, вызова  функции LoadLibrary() для  за грузки этой библиотеки DLL и, наконец, вызова  принадлежащей данной библиотеке DLL функции  DllGetClassObject(). После  получения указателя  на  интерфейс IClass- Factory, для создания экземпляра объекта заданного класса COM функция CoCre- ateInstance() вызывает функцию IClassFactory.CreateInstance().

CОВЕТ

Чтобы создать с помощью фабрики классов несколько объектов одного типа исполь- зовать функцию CreateComObject() неэффективно. Это объясняется тем, что после создания заданного объекта COM данная функция освобождает указатель на интер- фейс IClassFactory, полученный от функции CoGetClassObject(). Если необхо- димо создать несколько экземпляров одного и того же объекта COM, вызовите непо- средственно функцию CoGetClassObject(), а затем многократно обращайтесь к функции IClassFactory.CreateInstance() для создания необходимого количест- ва объектов.НА ЗАМЕТКУ

Перед использованием любой функции COM или API OLE нужно инициализировать биб- лиотеку COM, вызвав функцию CoInitialize() с единственным параметром nil. Для правильного отключения библиотеки COM следует вызвать функцию CoUninitial- ize() (это же справедливо и в отношении библиотеки OLE). Данные вызовы подсчиты- ваются системой, поэтому каждый вызов функции CoInitialize() в приложении дол- жен сопровождаться вызовом функции CoUninitialize().

В приложениях Delphi функция CoInitialize() вызывается автоматически из мето- да Application.Initialize(), а функция CoUninitialize() — при завершении работы модуля ComObj.

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

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии