Модель программирования Component Object Model. Разработка COM-сервера, страница 7

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

Логика функционирования нашего клиент-серверного проекта вырождена (излишне упрощена), так как мы хотели показать лишь основную нить алгоритма использования COM-объектов. Обычно в рамках этого алгоритма присутствуют 2 фундаментальных COM-интерфейса: IUnknown и IClassFactory. Для реализации так называемой фабрики классов нужен специальный класс на стороне сервера. Он должен предоставить миру (всем возможным клиентам) функциональность уже существующего и зарегистрированного в библиотеке COM интерфейса IClassFactory.

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

¨  Клиенты просят систему создать COM-сервер или дать доступ к нему, вызывая функции CoCreateInstance или CoGetClassObject. Первая API-функция вызывается для сообщения библиотекам COM о необходимости создать новый COM-сервер. Вторая функция вызывается для получения доступа к фабрике классов. Обычно это делается для создания нескольких серверов одного типа.

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

¨  Клиенты помогают освобождать COM-серверы, вызывая метод Release, а при необходимости и функции FreeLibrary или CoFreeUnusedLibraries. Вызывая в своих деструкторах одну из этих функций, они сообщают библиотекам OLE, что можно выгружать файл, содержащий COM-объект.

Интерфейсы

¨  Определяют протокол взаимодействия двух или более систем. Все общение между клиентом и COM-сервером происходит посредством интерфейсов. В модели COM они наследуемы.

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

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

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

¨  В соответствии с принятым соглашением имена COM-интерфейсов начинаются с буквы «I», например имена некоторых стандартных интерфейсов – IPropertyPage, IConnectionPoint, IPersistFile.

Библиотеки OLE

¨  Получают от клиента запрос на создание COM-сервера или доступ к нему через CLSID и интерфейс, и возвращают требуемый указатель.

Серверы

¨  Добавляют в реестр записи, которые связывают модуль сервера с уникальным CLSID.

¨  Реализуют фабрику классов для данного CLSID. Фабрика классов COM-сервера находится в том же исполняемом модуле, что и сам сервер и может быть реализована в самом COM-сервере.

¨  Обеспечивают механизм выгрузки. Когда система ищет память, или когда клиент вызывает CoFreeUnusedLibraries (или FreeLibrary), вызывается функция сервера DllCanUnloadNow. В зависимости от возвращаемого ею значения файл либо выгружается, либо нет. Если сервер обслуживает клиента, то возвращаемое значение должно быть FALSE.

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

¨  Создают COM-серверы заданного типа, то есть производят объекты с заданным CLSID.