- •107 Методические указания «Программное обеспечение сетей эвм. Часть 4. Версия 2. Развитие схемы «клиент-сервер» в com и corba»
- •Введение
- •1.1. Необходимость использования компонент
- •1.2. Методы встраивания компонентов
- •1.3. Основы com
- •1.4. Типы компонентов
- •1.5. Размещение управляющих элементов при помощи cWnd
- •1.6. Использование директивы #import
- •1.7. Компоновка тестовой программы
- •1.7.1 О компонентах
- •1.7.2 Регистрация компонентов
- •1.7.3 Импортирование библиотеки типов
- •1.7.4 Определение членов cDemoClientView
- •1.7.5 Создание компонентов
- •1.7.6 Создание точек взаимодействия
- •1.7.7 Синхронизация параметров
- •1.7.8 Обработка событий от компонентов
- •1.7.9 Очистка
- •1.7.10 Шаблонный код
- •1.9. Индивидуальные задания на работу
- •2.1. Проект. Основные принципы
- •2.2. Как создать компонент
- •Шаг 2: Создание компонента:
- •2.3. Значения по умолчанию
- •2.5. Индивидуальные задания на работу
- •3.1. Cоздание сервера com
- •3.2. Использование com-объектов
- •3.3. Индивидуальные задания на работу
- •Лабораторная работа № 4. Использование atl
- •4.1 Создание dcom-сервера с использованием atl
- •4.1.1 Введение в atl
- •4.1.2 Что такое atl?
- •4.1.3 Разделение труда
- •4.1.4 Создание хранилища компонентов с помощью atl Com AppWizard
- •4.1.5 Вставка кода заглушки/прокси-объекта.
- •4.1.7 Atl com-карта
- •4.1.9 Класс cComModule
- •4.1.10 Язык скриптов реестра в atl
- •4.1.11 Распределенная com (dcom)
- •4.1.12 Dcom и службы nt
- •4.1.13 Структура службы nt
- •4.1.14 Основанный на службах nt сервер сом
- •4.1.15 Создание проекта при помощи atl
- •4.1.16 Добавление функциональных средств
- •4.1.17 Функция CacheQuotes (dcomServiceXdcomService.Cpp)
- •4.1.18 Функция GetQuote (dcomServiceXdcomService.Cpp)
- •4.2 Создание dcom сервера
- •4.3 Создание dcom клиента
- •4.4 Индивидуальные задания на работу
- •Лабораторная работа № 5. Разработка corba приложений
- •5.1. Конфигурирование
- •5.2. Порядок действий
- •5.3. Объектно-ориентированный анализ и моделирование
- •5.4. Описание и трансляция объектов
- •5.5. Создание сервера
- •5.6. Создание клиента
- •5.7. Отладка объектов
- •5.8. Индивидуальные задания на работу
- •Лабораторная работа № 6. Адаптер роа
- •6.1. Архитектура poa
- •6.2. Политики poa
- •Политика обработки запросов
- •6.3. Создание серверов на основе poa
- •6.4. Индивидуальные задания на работу
- •Лабораторная работа № 7. Прикладная задача связи
- •7.1. Постановка задачи
- •7.1.1. Сотовая станция
- •7.1.2. Телефоны
- •7.1.3. Система
- •7.2. Функционирование системы
- •7.3. Индивидуальные задания на работу
- •Лабораторная работа № 8. Работа по умолчанию
- •8.1. Сервер с сервантом по умолчанию
- •8.2. Индивидуальные задания на работу
- •Лабораторная работа № 9. Создание менеджеров сервантов
- •9.1. Менеджеры сервантов
- •ServantActivator
- •ServantLocator
- •9.2. И снова практика
- •9.3. Индивидуальные задания на работу
- •Лабораторная работа № 10. Сервис именования
- •10.1. Сервис для именования (Naming Service)
- •10.2. Индивидуальные задания на работу
1.7.2 Регистрация компонентов
Перед использованием компонентов их нужно зарегистрировать в системе. Обычно регистрация выполняется автоматически при инсталляции программы или на этапе сборки программы при ее разработке в Visual C++. Если скомпилировать проект, содержащий демонстрационные компоненты, Visual C++ сам зарегистрирует компоненты на заключительном этапе сборки приложения. Однако, если когда-либо понадобится самостоятельно зарегистрировать компонент, содержащийся в библиотеке DLL, нужно будет просто запустить утилиту Windows regsvr32.exe и указать в командной строке путь к DLL-файлу. Например, если взять файл DemoComponents.dll и расположить его в папке C:\MyComponents, то можно зарегистрировать его, набрав в командной строке:
c:\windows\system\regsvr32 c:\mycomponents\democomponents.dll
(подразумевается, что Windows установлена в каталог C:\Windows).
Можно также отменить регистрацию компонента и удалить записи о нем из реестра, запустив regsvr32.exe с ключом -u, предваряющим путь к библиотеке, содержащей компоненты.
Если воспроизводится анализ демонстрационной программы, то надо откомпилировать проект DemoComponents, чтобы создать и зарегистрировать в системе используемые компоненты.
1.7.3 Импортирование библиотеки типов
Первый шаг интеграции COM-компонента в приложение состоит в обеспечении приложения достаточным количеством информации для создания компонента. Это можно сделать включением файла заголовков, содержащего глобально уникальные идентификаторы компонента (GUID) и определения классов интерфейсов. Но все же лучше использовать по отношению к библиотеке типов директиву #import, которая сделает то же самое, но кроме этого сгенерирует еще и классы-оболочки для интерфейсов.
Сложным моментом в этом процессе может стать поиск импортируемых компонентов или библиотек. Это не составит труда, если компонент разрабатывался самостоятельно, поскольку библиотека является частью проекта. А вот если, к примеру, нужно импортировать библиотеку типов Microsoft Outlook, найти ее не так просто. Один простых методов поиска нужной информации заключается в использовании программы OLE/COM Object Viewer, которая входит в комплект поставки Visual C++. Эта программа поможет обнаружить компоненты, интерфейсы и библиотеки типов, а также укажет путь к файлам библиотек, если только компоненты были зарегистрированы в системе. Чтобы импортировать информацию о компонентах из библиотеки типов, нужно добавить в начало файла заголовков DemoView.h строку
#import "..\DemoComponents\DemoComponents.tlb" no_namespace
Для указания пути используются те же соглашения, что для директивы #include, и в данном случае подразумевается, что папка проекта DemoComponents содержится в том же каталоге, что и папка проекта DemoClient. Библиотеки типов содержатся либо в отдельном файле TLB, либо в библиотеке DLL. Атрибут no_namespace указывает компилятору игнорировать любое определение пространства имен из библиотеки. Определения в большинстве библиотек заключаются в свои пространства имен с тем, чтобы избежать конфликтов имен с другими определениями в текущем пространстве имен. Директиву no_namespace можно использовать, если есть уверенность в отсутствии конфликтов определений; в противном случае можно использовать директиву rename_attribute для переименования конфликтующих определений. Подробнее о всех возможностях можно прочитать в разделе MSDN, посвященном #import.
После того, как импортирована информация из библиотек типов и откомпилирован проект, компилятор попытается прочесть информацию из указанного файла. Если эта операция выполнится успешно, он сгенерирует классы оболочки, основанные на шаблоне _com_ptr_t<>, для интерфейсов, определенных в библиотеке типов. Эта информация будет размещена в двух файлах: файле заголовков с расширением TLH и файле реализации с расширением TLI. Эти файлы неявно включаются в проект в области видимости директивы #import, так что можно использовать сгенерированные классы. Возможно также явно подключить файл TLH, если надо, чтобы сгенерированные классы отображались в окне ClassView. Если используется Visual C++ 6.0 или более поздний, информация о сгенерированных классах будет сохранена в проекте. В результате об этих классах узнает IntelliSense и сможет показывать подсказки для методов и свойств членов интерфейсов и для параметров методов во время их ввода. Он также добавляет определения в сгенерированный TLH-файл заголовков с тем, чтобы можно было использовать имена компонентов и интерфейсов вместо их GUID для таких методов, как CWnd::CreateControl().
Применительно к данным демонстрационным компонентам, после компиляции проекта созданы классы-оболочки для интерфейсов IDemoModelPtr, IDemoViewPtr, IDemoControllerPtr, IDemoModelConnectionPtr и _IDemoControllerEventsPtr. Название каждого сгенерированного класса содержит название интерфейса, к которому добавлено окончание "Ptr". Интерфейсы IDemoModelConnection и _IDemoControllerEvents - исходящие (outgoing), так что это просто базовые классы, в использовании которых напрямую особого смысла нет. Далее рассмотрено как при помощи остальных трех классов-оболочек получить доступ к методам интерфейсов, и как использовать два оставшихся интерфейса.