Библиотеки типов
СОМ-объекты часто используют библиотеки типов. Библиотека типов - это специальный файл, который содержит информацию о СОМ-объекте. Данная информация содержит список свойств, методов, интерфейсов, структур и других элементов, которые содержатся в СОМ-объекте. Библиотека типов содержит также информацию о типах данных каждого свойства и Типах данных, возвращаемых методами СОМ-объекта.
Файлы библиотеки типов имеют расширение TLB.
Фабрика класса
СОМ-объекты представляют собой экземпляры coclass. Напомним, что Coclass - это класс, поддерживающий один или более интерфейс. СОМ-объекты могут предоставлять только те услуги, которые определены в интерфейсах coclass. Экземпляры Cociass создаются при помощи специального типа объекта, называемого фабрикой класса.
Фабрика класса - это специальный СОМ-объект, который поддерживает интерфейс IclassFactory и отвечает за создание экземпляров того класса, с которым ассоциирована данная фабрика класса.
Интерфейс IclassFactory определен в модуле Delphi ActiveX так:
type
IClassFactory = interface (IUnknown)
['{00000001-0000-0000-COOO-000000000046}']
function Createlnstance (const unkOuter: lUnknown; const iid: TIID out obj): HResult; stdcall;
function LockServer (fLock: BOOL): HResult; stdcall;
end;
Как видно из вышеприведенного куска кода, интерфейс имеет два метода:
Createlnstance и LockServer.
Метод Createlnstance создает экземпляр СОМ-объекта ассоциированной фабрики класса.
Метод LockServer применяется для хранения СОМ-сервера в памяти. Если параметр метода fLock имеет значение true, то счетчик ссылок сервера увеличивается, иначе - уменьшается. Когда счетчик достигает значения о, сервер выгружается из памяти.
Всякий раз, когда услуги СОМ-объекта запрашиваются клиентом, фабрика класса создает и регистрирует экземпляр объекта для конкретного пользователя. Если услуга того же СОМ-объекта запрашивает другой клиент, фабрика класса создает второй экземпляр объекта для обслуживания второго клиента. coclass должен иметь фабрику класса и идентификатор класса CLSID. Использование CLSID для cociass подразумевает, что они могут быть откорректированы всякий раз, когда в класс вводятся новые интерфейсы. Таким образом, в отличие от DLL, новые интерфейсы могут изменять или добавлять методы, не влияя на старые версии.
Мастер создания СОМ-объектов Delphi самостоятельно заботится о создании фабрики класса.
Локальные и удаленные серверы
С использованием СОМ клиент не должен беспокоиться о том, где располагается объект, он просто делает вызов интерфейса данного объекта. Технология СОМ обеспечивает все необходимые шаги для того, чтобы сделать этот вызов. Шаги могут отличаться, в зависимости от местонахождения объекта. Объект может находиться в том же процессе, где и клиент, в другом процессе на том же компьютере, где расположен клиент, или на другом компьютере в сети. В зависимости от этого применяются разные типы серверов:
- внутренний сервер (In-process server);
- локальный сервер или сервер вне процесса (Local server, Out-of-process server);
- удаленный сервер (Remote server).
Внутренний сервер - это библиотека DLL, которая запущена в одном процессе вместе с клиентом. Например, элемент управления ActiveX, который внедрен на Web-страницу и просматривается при помощи Internet Explorer или Netscape Navigator. В данном случае элемент управления ActiveX загружен на клиентскую машину и находится в том же процессе, что и обозреватель Web. Приложение-клиент связывается с сервером внутри процесса при помощи прямых вызовов СОМ-интерфейса. На рис. 3.3. представлена схема взаимодействия клиента с внутренним сервером.
![](image/3-3.jpg)
Рис. 3.3. Схема взаимодействия клиента с внутренним сервером
Внутренний СОМ-сервер должен экспортировать четыре функции:
function DllRegisterServer: HResult; stdcall;
function DllUnregisterServer: HResult; stdcall;
function DllGetClassObject (const CLSID, IID: TGUID; var Obj): HResult;
stdcall;
function DllCanUnloadNow: HResult; stdcall;
Все вышеперечисленные функции уже реализованы в модуле comserv, их нужно только добавить в описания exports вашего проекта.
Рассмотрим данные функции более подробно:
- DllRegisterServer - применяется для регистрации DLL СОМ-сервера в системном реестре Windows. При регистрации СОМ-класса в системном реестре создается раздел в HKEY_CZASSES_ROOT\CLSID\{XXXXXXXX-XXXX-XXXX-xxxx-xxxxxxxx}, где число, записанное вместо символов х, представляет собой CLSID данного СОМ-класса. Для внутреннего сервера в данном разделе создается дополнительный подраздел inProcserver32. В этом подразделе указывается путь к DLL внутреннего сервера (рис. 3.4).
- DllUnregisterServer - применяется для удаления всех разделов, подразделов и параметров, которые были созданы в системном реестре функцией DllRegisterServer при регистрации DLL СОМ-сервера.
- DllGetclassObject - возвращает фабрику класса для конкретного СОМ-класса.
- DllcanUnloadNow - применяется для определения, можно ли в настоящий момент времени выгрузить DLL СОМ-сервера из памяти. Функция проверяет, есть ли указатели на любой СОМ-объект данной DLL, если есть, то возвращает значение S_FALSE, т. е. DLL выгрузить нельзя. Если ни один СОМ-объект данной DLL не используется, то функция возвращает значение SJTRUE.
![](image/3-4.jpg)
Рис. 3.4. Путь к локальному СОМ-серверу в окне редактора системного реестра
Локальный сервер - это приложение ЕХЕ, которое запущено в другом процессе, но на одном компьютере вместе с клиентом. Например, лист электронной таблицы Microsoft Excel связан с документом Microsoft Word. При этом два разных приложения работают на одном компьютере. Локальные серверы используют СОМ для соединения с клиентом.
Когда клиент и сервер находятся в различных приложениях, а также, когда они находятся на разных компьютерах в сети, СОМ использует внутренний (внутрипроцессный) прокси (In-process proxy) для реализации процедуры удаленного вызова. Прокси располагается в одном процессе вместе с клиентом, поэтому, с точки зрения клиента, вызов интерфейсов осуществляется так же, как и в случае, когда клиент и сер'вер находятся внутри одного процесса. Задача прокси заключается в том, чтобы перехватывать вызовы клиента и перенаправлять их туда, где запущен сервер. Механизм, который позволяет клиенту получать доступ к объектам, расположенным в другом адресном пространстве или на другом компьютере, называется маршалинг (marshaling).
Функции маршалинга:
- принимать указатель интерфейса из процесса сервера и делать указатель прокси в процессе клиента доступным;
- передавать аргументы вызовов интерфейса таким образом, как будто они произошли от клиента и размещать аргументы в процесс удаленного объекта.
Для любого вызова интерфейса клиент помещает аргументы в стек, вызывает необходимую функцию СОМ-объекта через указатель интерфейса. Если вызов объекта произошел не внутри процесса, вызов проходит через прокси. Прокси упаковывает аргументы в пакет маршалинга и передает получившуюся структуру удаленному объекту. Заглушка (stub) объекта распаковывает пакет маршалинга, выбирает аргументы из стека и вызывает необходимую функцию СОМ-объекта.
Таким образом, маршалинг - это процесс упаковки информации, а демаршалинг - процесс распаковки информации.
Тип маршалинга зависит от объектной принадлежности СОМ. Объекты могут использовать стандартный механизм маршалинга, предоставляемый интерфейсом IDispatch. Стандартный маршалинг позволяет устанавливать связь при помощи стандартного системного удаленного вызова процедуры (Remote Procedure Call, RFC).
На рис. 3.5 изображена схема, показывающая методику взаимодействия клиента и сервера в случае, когда приложения работают на одном компьютере, но в разных приложениях.
![](image/3-5.jpg)
Рис. 3.5. Схема взаимодействия клиента с сервером в разных процессах на одном компьютере
Локальный СОМ-сервер регистрируется в системном реестре Windows так же, как и внутренний СОМ-сервер.
Удаленный сервер - это библиотека DLL или иное приложение, запущенное на другом компьютере. То есть клиент и сервер работают на разных компьютерах в сети. Например, приложение базы данных, написанное с помощью Delphi, соединяется с сервером на другом компьютере в сети. Удаленный сервер использует распределенные СОМ-интерфейсы (Distributed COM, DCOM) для связи с клиентом.
Удаленный сервер работает также с помощью прокси. Различие в работе между локальным и удаленным сервером заключается в типе используемой межпроцессной связи. В случае локального сервера - это СОМ, а в случае удаленного сервера - DCOM. Схема взаимодействия клиента и удаленного сервера показана на рис. 3.6.
![](image/3-6.jpg)
Рис. 3.6. Схема взаимодействия клиента с сервером на разных компьютерах
OLE-объекты
Часть данных, использующаяся совместно несколькими приложениями, называется OLE-объектом. Те приложения, которые могут содержать в себе OLE-объекты, называются OLE-контейнерами (OLE container). Приложения, имеющие возможность содержать свои данные в OLE-контейнерах, называются OLE-серверами (OLE server).
Основной СОМ-интерфейс IUnknown
Базовый интерфейс lunknown достаточно подробно был рассмотрен во второй главе книги. В дополнение ко всему вышесказанному, добавим, что интерфейс lunknown обеспечивает механизм учета ссылок (счетчик ссылок на СОМ-объект). При передаче указателя на интерфейс выполняется метод интерфейса lunknown AddRef. По завершении работы с интерфейсом приложение-клиент вызывает метод Release, который уменьшает счетчик ссылок.
При вызове метода Querylnterface интерфейса Iunknown в метод передается параметр IID, имеющий тип TGUID, т. е. идентификатор интерфейса. Параметр метода out возвращает либо ссылку на запрашиваемый интерфейс, либо значение NH. Результатом вызова метода может быть одно из значений, перечисленных в табл. 3.1.
Таблица 3.1. Значения, возвращаемые методом Queryinterface
Значение |
Описание |
||
S_OK |
Интерфейс поддерживается |
||
E_NOINTERFACE |
Интерфейс не поддерживается |
||
E_UNEXPECTED |
Неизвестная ошибка |
||
Пользователь СОМ-объекта
Пользователем СОМ-объекта называется приложение или часть приложения, которое использует СОМ-объект и его интерфейсы в своих собственных целях. Как правило, СОМ-объект находится в другом приложении.
Расширения СОМ
Технология СОМ изначально разрабатывалась как ядро для осуществления межпрограммного взаимодействия. Уже на этапе разработки предполагалось расширять возможности технологии при помощи так называемых расширений СОМ. СОМ расширяет собственную функциональность, благодаря созданию специализированных наборов интерфейсов для решения конкретных задач.
Технология ActiveX - это технология, которая использует компоненты СОМ, особенно элементы управления. Она была создана для того, чтобы работа с элементами управления была более эффективной. Это особенно необходимо при работе с приложениями Internet/Intranet, в которых элементы управления должны быть загружены на компьютер клиента, прежде чем они будут использоваться.
Технология ActiveX - не единственное расширение СОМ. В табл. 3.2 представлены некоторые из используемых в настоящее время расширений СОМ.
Перечисленные в табл. 3.2 расширения СОМ - это далеко не все из имеющихся. Постоянно идет доработка старых и создание новых, более совершенных технологий межпрограммного взаимодействия.
Таблица 3.2. Список расширений СОМ
Расширение СОМ |
Краткое описание |
||
Серверы автоматизации (Automation servers) |
Серверы автоматизации- это объекты, которыми можно управлять из других приложений во время работы приложения. Таким образом, автоматизация- это способность приложения программно контролировать объекты других приложений |
||
Диспетчеры автоматизации или СОМ-клиенты (Automation Controllers, COM Clients) |
Диспетчеры автоматизации- это клиенты серверов автоматизации. Они позволяют разработчику или пользователю писать сценарии для управления серверами автоматизации |
||
Элементы управления ActiveX (ActiveX Controls) |
Элементы управления ActiveX предназначены для серверов внутри процесса (in-process COM servers). Элементы ActiveX обычно используются путем встраивания в приложение-клиент |
||
Библиотеки типов (Type Libraries) |
Библиотеки типов представляют собой статичные структуры данных, которые часто сохраняются как файлы ресурсов. Они содержат детализированную информацию об объекте и его интерфейсах. Клиенты серверов автоматизации и элементы управления ActiveX используют данную информацию и всегда считают ее доступной |
||
Страницы активного сервера (Active Server Pages) |
Активные серверные страницы- это компоненты ActiveX, которые позволяют вам создавать динамически изменяющиеся Web-страницы |
||
Активные документы (Active Documents) |
Активные документы - это объекты, которые поддерживают связывание и внедрение, визуальное редактирование, перенос (drag-and-drop). В качестве примера таких документов можно представить документы Microsoft Word и книги Microsoft Excel |
||
Визуальные межпроцессные объекты (Visual Cross-process Objects) |
Визуальные межпроцессные объекты- это визуальные объекты, которыми можно управлять из других процессов |
||
На рис. 3.7 представлена диаграмма, которая показывает связь некоторых расширений СОМ и их связь с технологией СОМ.
Использование СОМ-объектов имеет как преимущества, так и некоторые ограничения. СОМ-объекты могут быть как визуальными, так и невизуальными. Какие-то СОМ-объекты должны быть запущены в одном процессе с клиентом, другие - в разных процессах либо на разных,,компьютерах.
Приведенная ниже табл. 3.3 кратко описывает особенности объектов каждого из вышеприведенных расширений СОМ.
![](image/3-7.jpg)
Рис. 3.7. Технологии, основанные на СОМ
Таблица 3.3. Особенности объектов СОМ
СОМ-объект |
Визуаль-ность |
Процесс |
Связь |
Библиотека типов |
||
Активный документ (Active Document) |
Обычно визуальный |
Внутренний или локальный |
OLE |
Нет |
||
Автоматизация (Automation) |
Может быть как визуальным, так и невизуальным |
Внутренний, локальный или удаленный |
Автоматический маршалинг при помощи интерфейса
IDispatch |
Требуется для автоматического маршалмнга |
||
Элемент управления ActiveX (ActiveX Control) |
Обычно визуальный |
Внутренний |
Автоматический маршалинг при помощи интерфейса
IDispatch |
Требуется |
||
Произвольный объект интерфейса |
По выбору |
Внутренний |
Не требуется маршалинг |
Рекомендуется |
||
Произвольный объект интерфейса |
По выбору |
Внутренний, локальный или удаленный |
Автоматический маршалинг в зависимости от библиотеки типов, в противном случае-ручной маршалинг |
Рекомендуется |
||
Развитие СОМ-технологий
Одной из важнейших задач, которые ставила перед собой фирма Microsoft, когда продвигала операционную систему Windows, была задача по обеспечению эффективного взаимодействия между различными программами, работающими в Windows.
Самыми первыми попытками решить эту непростую задачу были буфер обмена, разделяемые файлы и технология динамического обмена данными (Dynamic Data Exchange, DDE).
После чего была разработана технология связывания и внедрения объектов (Object Linking and Embedding, OLE). Первоначальная версия OLE 1 предназначалась для создания составных документов. Эта версия была признана несовершенной и на смену ей пришла версия OLE 2. Новая версия позволяла решить вопросы предоставления друг другу различными программами собственных функций. Данная технология активно внедрялась до 1996 года, после чего ей на смену пришла технология ActiveX, которая включает в себя автоматизацию (OLE-автоматизацию), контейнеры, управляющие элементы, Web-технологию и т. д.
Счетчики ссылок
Каждый СОМ-объект имеет счетчик ссылок. Данный счетчик содержит число процессов, которые в текущий момент времени используют СОМ-объект. Под процессом здесь подразумевается любое приложение или DLL, которые используют СОМ-объект, т. е. пользователи СОМ-объекта. Счетчик ссылок на СОМ-объект нужен для того, чтобы высвобождать процессорное время и оперативную память, занимаемую СОМ-объектом, в том случае, когда он не используется.
После создания и обращения к СОМ-объекту счетчик ссылок увеличивается на единицу. Всякий раз, когда новое приложение подключается к СОМ-объекту - счетчик увеличивается. Когда процесс отключается от СОМ-объекта - счетчик уменьшается. При достижении счетчиком нуля память, занимаемая СОМ-объектом, высвобождается.
СОМ-интерфейс
Клиенты СОМ связываются с объектами при помощи СОМ-интерфейсов. Интерфейсы -- это группы логически или семантически связанных процедур, которые обеспечивают связь между поставщиком услуги (сервером) и его клиентом. На рис. 3.1 схематично изображен стандартный СОМ-интерфейс.
![](image/3-1.jpg)
Рис. 3.1. СОМ-интерфейс
Примечание
По правилам обозначения СОМ-объектов, интерфейсы СОМ-объекта обозначаются кружками справа или слева от СОМ-объекта. Базовый интерфейс lUnknown рисуется кружком сверху от СОМ-объекта.
Для примера, каждый СОМ-объект всегда поддерживает основной СОМ-интерфейс lUnknown, который применяется для передачи клиенту сведений о поддерживаемых интерфейсах.
Как уже говорилось выше, СОМ-объект может иметь несколько интерфейсов, каждый из которых обеспечивает какую-либо свою функцию.
Ключевыми аспектами СОМ-интерфейсов являются следующие.
- Однажды определенные, интерфейсы не могут быть изменены. Таким образом, вы можете возложить на один интерфейс определенный набор функций. Дополнительную функциональность можно реализовать с помощью дополнительных интерфейсов.
- По взаимному соглашению, все имена интерфейсов начинаются с буквы I, например IPersist, IMalloc.
- Каждый интерфейс гарантированно имеет свой уникальный идентификатор, который называется глобальный уникальный идентификатор (Globally Unique Identifier, GUID). Уникальные идентификаторы интерфейсов называют идентификаторами интерфейсов (Interface Identifiers, IIDs). Данные идентификаторы обеспечивают устранение конфликтов имен различных версий приложения или разных приложений.
- Интерфейсы не зависят от языка программирования. Вы можете воспользоваться любым языком программирования для реализации СОМ-интерфейса. Язык программирования должен поддерживать структуру указателей, а также иметь возможность вызова функции при помощи указателя явно или неявно.
- Интерфейсы не являются самостоятельными объектами, они лишь обеспечивают доступ к объектам. Таким образом, клиенты не могут напрямую обращаться к данным, доступ осуществляется при помощи указателей интерфейсов.
- Все интерфейсы всегда являются потомками базового интерфейса Iunknown.
СОМ-интерфейсы
СОМ-интерфейс применяется для объединения методов СОМ-объекта. Интерфейс позволяет клиенту правильно обратиться к СОМ-объекту, а объекту - правильно ответить клиенту. Названия СОМ-интерфейсов начинаются с буквы I. Клиент может не знать, какие интерфейсы имеются у СОМ-объекта. Для того чтобы получить их список, клиент использует базовый интерфейс lunknown, который есть у каждого СОМ-объекта.
СОМ-классы
СОМ со-классы (coclass) - это классы, которые содержат один или более СОМ-интерфейс. Вы можете не обращаться к СОМ-интерфейсу непосредственно, а получать доступ к СОМ-интерфейсу через со-класс. Со-классы идентифицируются при помощи идентификаторов класса (CLSID).
СОМ-клиенты
Очень важным при разработке СОМ-приложений является создание приложений, называемых СОМ-клиентами, которые могут запрашивать интерфейсы объектов, чтобы определить те услуги, которые может предоставить СОМ-объект.
Типичным СОМ-клиентом является диспетчер автоматизации (Automation Controller). Диспетчер автоматизации - это часть приложения, которая знает какой тип информации необходим ему от.разных объектов сервера, и она запрашивает данную информацию по мере надобности.
СОМ-объект
СОМ-объект представляет собой двоичный код, который выполняет какую-либо функцию и имеет один или более интерфейс.
СОМ-объект содержит методы, которые позволяют приложению пользоваться СОМ-объектом. Эти методы доступны благодаря СОМ-интерфейсам. Клиенту достаточно знать несколько базовых интерфейсов СОМ-объекта, чтобы получить полную информацию о составе свойств и методов объекта. СОМ-объект может содержать один или несколько интерфейсов. Для программиста СОМ-объект работает так же, как и класс в Object Pascal.
СОМ-серверы
СОМ-сервер представляет собой приложение или библиотеку, которая предоставляет услуги приложению-клиенту или библиотеке. СОМ-сервер содержит один или более СОМ-объектов, где СОМ-объекты выступают в качестве наборов свойств, методов и интерфейсов.
Клиенты не знают как СОМ-объект выполняет свои действия. СОМ-объект предоставляет свои услуги при помощи интерфейсов., В дополнение, приложению-клиенту не нужно знать, где находится СОМ-объект. Технология СОМ обеспечивает прозрачный доступ независимо от местонахождения СОМ-объекта.
Когда клиент запрашивает услугу от СОМ-объекта, он передает СОМ-объекту идентификатор класса (CLSID). CLSID - всего лишь GUID, который применяется при обращении к СОМ-объекту. После передачи CLSID, СОМ-сервер должен обеспечить так называемую фабрику класса (см. следующий раздел), которая создает экземпляры СОМ-объектов.
В общих чертах, СОМ-сервер должен выполнять следующее:
- регистрировать данные в системном реестре Windows для связывания модуля сервера с идентификатором класса (CLSID);
- предоставлять фабрику СОМ-класса, создающую экземпляры СОМ-объектов;
- обеспечивать механизм, который выгружает из памяти серверы СОМ, которые в текущий момент времени не предоставляют услуг клиентам.
Примечание
Для создания СОМ-объектов и СОМ-серверов Delphi предоставляет мастера, который значительно упрощает процедуру. Об этом читайте следующую главу.
Состав СОМ-приложения
При создании СОМ-приложения необходимо обеспечить следующее:
- СОМ-интерфейс;
- СОМ-сервер;
- СОМ-клиент.
Рассмотрим эти три составляющие СОМ-приложения более подробно.
Составные документы
Документ, включающий в себя один или несколько OLE-объектов, называется составным документом. Приложение, которое может содержаться внутри документа, называется ActiveX-документом (ActiveX document).
Остальные термины, присущие технологии СОМ, мы рассмотрим в следующих разделах данной книги.
Технология DCOM
Технология DCOM (Distributed COM) - это распределенная СОМ-технология. Она применяется для предоставления средств доступа к СОМ-объектам, расположенным на других компьютерах в сети (в том числе и сети Internet).
Операционные системы Windows NT 4 и Windows 98 имеют встроенную поддержку DCOM.
Терминология СОМ
Всякая новая технология приносит с собой новые термины для ее описания.
Указатели СОМ-интерфейса
Указатель интерфейса - это 32-битный указатель на экземпляр объекта, который является, в свою очередь, указателем на реализацию каждого метода интерфейса. Реализация методов доступна через массив указателей на эти методы, который называется vtable. Использование массива vtable похоже на механизм поддержки виртуальных функций в Object Pascal.
![](image/3-2.jpg)
Рис. 3.2. Схема работы указателя СОМ-интерфейса
Наглядное представление работы указателей СОМ-интерфейса представлено на рис. 3.2.