Смекни!
smekni.com

Разработка приложений в рамках COM (стр. 2 из 4)

· Интерфейс не может измениться после регистрации в системе. Каждый интерфейс предназначен для выполнения определенной задачи, и определяет, какие данные поступают на обработку и какие данные выводятся. Таким образом, после того, как интерфейс опубликован в системе, и стал доступен для использования, он не должен меняться. Любое изменение в семантике интерфейса ведет к необходимости оявления нового интерфейса. Однако существует возможность безопасной реализации многоинтерфейсных объектов посредством использования для доступа к разным версиям интерфейса разные IID.

· Интерфейсы наследуют функциональность от одного базового предка. Все интерфейсы прямо или косвенно являются потомками интерфейса IUnknown. Этот интерфейс обеспечивает базовую функциональность интерфейса, которая включает в себя динамический опрос объекта (dynamic quering) и управление жизненным циклом объекта (lifetime managment). Эта функциональность обеспечивается тремя методами интерфейса IUnknown: QueryInterface, AddRef и Release. Каждый класс, который реализует интерфейс, должен реализовать эти три метода, наряду с методами, унаследованные от другого интерфейса, и своими собственными методами. Ниже представлено краткое описание функционального назначения упомянутых методов:

- QueryInetrface обеспечивает опрос объекта и доступ к указателю на интерфейс. QueryInerface является первой записью в vtable, и предлагает эффективный путь для определения возможностей объекта, в простейшем случае через этот метод при установлении связи обеспечивается передача указателя на интерфейс IUnknown тому объекту, который пытается получить доступ к данному объекту. Данный метод также делает возможным обновление COM объекта без потерь на обновление остальных зависимых объектов, т.к. объект может быть динамически опрошен клиентами через указатель на IUnknown. Это функция носит название dynamic quering;

- AddRef и Release находятся на втором и третьем местах в vtable. Это простые счетные функции, которые предоставляются для управления временем жизни объекта. Пока внутренний счетчик объекта, отражающий количества раз вызова AddRef и Release больше нуля (вызов AddRef может увеличивать его значение), объект остается в памяти. Как только значение счетчика достигает нуля (вызов Release может уменьшать его значение), реализация интерфейса может безопасно удалить все зависимые нижележащие объекты. Это функция носит название lifetime managment;

2.3. Свойства COM-объектов

COM-объект – это объект CoClass, который является классом, реализующим один или более интерфейсов. COM-объект предоставляет функции, которые доступны через указатель на один из его интерфейсов. Всвязи с этим, COM-объект обладает следующими особенностями:

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

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

2.4. COM-серверы

Объект COM-класса должен иметь в своем составе фабрику классов, и идентификатор класса CLSID (Class Identifier), так чтобы COM-объект мог быть создан на основе существующего модуля.

COM-сервер – это приложение, или библиотека, предоставляющее определенный набор сервисных функций для клиентских приложений или библиотек.

COM-сервер состоит из COM-объектов. Например, COM-сервер, который включает в себя код элементов управления ActiveX (ActiveX control)– является ActiveX-сервером. Для разработчика имеется большое число библиотек, которые можно использовать для создания COM-объектов. В качестве примера можно привести библиотеку Microsoft Active Template Library, предоставляющую набор шаблонов, на основе которых можно создавать свои собственные программные продукты, построенные по COM-технологии. Например, шаблон для COM-сервера включает в себя код для основных функций, которые должен обеспечивать COM-сервер: регистрация сервера в системе, загрузка/выгрузка сервера, создание объектов, управления фабриками классов, обеспечение выдачи информации о сервере, включая: тип сервера, help-файл, имя сервера, библиотека типов и т.д.

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

· In-process server (внутренний сервер) – программный DLL модуль, работающий в рабочем пространстве памяти клиентского приложения:


· Local server (локальный сервер) – программный EXE модуль, работающий в отдельном адресном пространстве;

· Remote server (удаленный сервер) – программный EXE модуль, работающий на удаленной машине:

2.5. Механизм маршаллинга

Разница между внутренним и удаленным серверами в том, какой тип межпроцессной связи используется. В данном случае существует необходимость использования посредников, которые обеспечивают передачу параметров и вызов функций. Такой механизм называется маршаллингом (marshalling). Т.к. в случае, когда клиент и сервер находятся в разных адресных пространствах, доступ к ресурсам не может быть осуществлен непосредственно через указатели. Поэтому посредники со стороны клиента (proxy) осуществляют упаковку аргументов в пакеты маршаллинга (marshalling packets), и обеспечивают удаленный вызов процедур (Remote Procedure Call). Посредник со стороны сервера (stub) реализуют распаковку параметров, и помещение их в стек. Далее осуществляется вызов непосредственно реализации метода. По сути, сервер создает клиентский вызов процедуры в своем собственном адресном пространстве.


Посредники используют COM-средства, для осуществления взаимодействия в разных процессах. Для взаимодействия объектов, находящихся на разных машинах, используются средства расширения COM – распределенная COM (Distributed COM или DCOM). COM предлагает стандартный механизм маршаллинга – интерфейс диспетчеризации (Dispatch Interface).

2.6. Фабрики классов

Фабрики или производители классов (class factories) - специальный тип COM-объектов, используемый для создания и регистрации COM-объектов. Производители классов реализуют стандартный механизм создания объектов COM-классов. Классы без идентификаторов класса (CLSID) и фабрики классов могут быть созданы посредством вызова конструктора. Использование фабрики классов для создания объектов означает, что для клиентского приложения, которому необходимо создать объект класса, не нужно знать об этом классе ничего, кроме его идентификатора CLSID. Фабрика классов возьмет вызов конструктора на себя, включая передачу аргументов в конструктор и остальные специфичные действия. Класс фабрики классов может быть объединен со многими COM-классами, для каждого из которых могут создаваться объекты. При создании же объекта фабрики классов, в конструктор передается идентификатор CLSID класса, для создания объектов которого предназначается фабрика. Этот идентификатор определяет, объекты какого класса могут быть созданы с помощью данной фабрики классов. Таким образом, каждый экземпляр фабрики классов в системе может быть использован для создания объектов только одного определенного класса.

Создание объекта класса производится посредством следующих действий:

· вызова глобальной API-функции CoGetClass, которая ищет в системном реестре зарегистрированный класс с данным CLSID, определяет путь к серверу, загружает сервер и выдает указатель на интерфейс производителя классов (обычно IClassFactory);

· Указатель на IСlassFactory может быть использован для вызова методов производителя классов, например: CoCreateInstance (создание объекта);

Альтернативой рассмотренному методу может служить вызов глобальной API-функции CoCreateInstance, которая выполняет перечисленный выше действия и создает объект класса с идентификатором CLSID, но таким образом можно создать только один объект данного класса, т.к. функция не возвращает указатель на интерфейс производителя классов.

2.7. Библиотеки типов

Библиотека типов (type library) предоставляет информацию об используемых типах объектов и интерфейсах, которые предоставляются ActiveX-серевером. Библиотека типов по смыслу аналогична, например, заголовочному файлу (header) для разработок на языке C и любому другому модулю, содержащему информацию об используемых типах данных и объектах. Большинство информации подобного рода может быть записано в библиотеку типов. Получить информацию из библиотеки типов можно путем опроса запущенного объекта или же посредством загрузки непосредственно библиотеки типов. После создания библиотеки типов, к ней обеспечивается доступ через специальный тип интерфейсов: ITypeLib, ITypeInfo и ITypeComp. Интерфейс ITypeLib обеспечивает доступ к информации о типах в библиотеке типов, а также к описаниям конкретных объектов, которые, в свою очередь, могут быть получены через интерфейс ITypeInfo.

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

· Описания пользовательских типов данных, связанных с пользовательскими интерфейсами;

· Функции, которые экспортируются ActiveX-сервером, но которые не являются интерфейсными методами;