Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Роджерсон Д. - Основы COM - 2000.pdf
Скачиваний:
412
Добавлен:
13.08.2013
Размер:
2.4 Mб
Скачать

103

Обратите внимание, что DllGetClassObject обладает подобными знаниями о создаваемой ею фабрике класса, а IClassFactory::CreateInstance — о создаваемом компоненте. Эти функции изолируют клиент от деталей реализации компонента. Можно сделать эти функции пригодными для повторного использования, однако в том или ином месте им обязательно потребуются специфические знания о том, как создавать конкретную фабрику класса или конкретный компонент. Способы, используемые DllGetClassObject и IClassFactory::CreateInstance для создания компонентов, полностью оставлены на усмотрение разработчика. Повторно применимая реализация

DllGetClassObject и IClassFactory::CreateInstance будет представлена в гл. 9.

Последовательность выполнения

Двайте подробно рассмотрим последовательность выполнения кодов клиента и компонента, приведенных в листингах 7-1 и 7-2. На рис. 7-2 эта последовательность представлена графически. Ось времени на рисунке направлена вниз. Пяти основным структурным элементам — клиенту, библиотеке COM, DLL, фабрике класса и компоненту — соответствуют отдельные колонки. С каждым элементом связана вертикальная линия. Сплошная линия означает, что данный элемент был создан и все еще существует. Пунктирная линия показывает, что элемент еще или уже не существует. Прямоугольники, нанесенные поверх линий, соответствуют временам выполнения операций. Горизонтальные линии — это вызовы функций, передающие управление от одного структурного элемента к другому.

Время

Клиент

Библиотека COM

DLL

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

Компонент

CoCreateInstance CoGetClassObject

DllGetClassObject

new CFactory

IClassFactory::CreateInstance(IID_IX)

new CA

IClassFactory::Release

pIX->Fx()

Рис. 7-2 CoCreateInstance позаботится за клиента о множестве мелких деталей создания компонента

Для простоты я опустил вызовы членов IUnknown и другие мелкие подробности. Кратко рассмотрим содержание рисунка. Сначала клиент вызывает CoCreateInstance, которая реализована в библиотеке СОМ. CoCreateInstance реализована с помощью CoGetClassObject. CoGetClassObject отыскивает компонент в Реестре. Если компонент найден, то CoGetClassObject загружает DLL, являющуюся сервером компонента. После загрузки DLL

CoGetClassObject вызывает DllGetClassObject. DllGetClassObject реализована DLL-сервером. Ее задача — создать фабрику класса, что делается в данном примере при помощи оператора new С++. Кроме того, DllGetClassObject запрашивает у фабрики класса интерфейс IClassFactory, который возвращается CoCreateInstance. Последняя вызывает метод CreateInstance этого интерфейса. В нашем примере IClassFactory::CreateInstance использует для создания компонента оператор new. Кроме того, она запрашивает у компонента интерфейс IX. Получив его, CoCreateInstance освобождает фабрику класса и возвращает указатель на IX клиенту. Затем клиент может использовать данный указатель для вызова методов компонента. Проще некуда.

Регистрация компонента

Компоненты DLL экспортируют четыре функции. Мы уже рассмотрели DllGetClassObject, которую функции библиотеки COM используют для создания фабрики класса. Три других экспортируемые функции используются для регистрации компонента.

Функции DllRegisterServer и DllUnregisterServer регистрируют и удаляют из Реестра Windows информацию о компоненте. Мы кратко рассматривали их в гл. 6. Реализованы эти функции в файле REGISTRY.CPP. Я не буду объяснять их код — он достаточно прост, и при желании Вы сможете разобраться сами. Мы будем использовать тот же файл REGISTRY.H для регистрации компонентов и в последующих главах книги.

Make-файл примера этой главы содержит строку

regsvr32 –s Cmpnt.dll

Соседние файлы в предмете Программирование на C++