- •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. Индивидуальные задания на работу
3.2. Использование com-объектов
Использование в среде Visual J++ созданного в ней же объекта не сложнее, чем любого другого COM-объекта, и строится на разборе библиотеки типов. Обратимся к примеру. Командой File•New Project•New•Applications доберемся до мастеров создания оконных приложений. Нас интересует Windows Application. После создания такого проекта в форму окна приложения помещаются две кнопки: «Запустить Word» и «Закончить сеанс Windows». Как вы, наверное, уже догадались, в обработчиках нажатий этих кнопок и будут вызываться методы объекта. Но об этом чуть позже.
Главный вопрос: как обратиться к COM-объекту? Для этого мы должны создать «обертки», которые позволят обратиться из класса Java в сущность, нейтральную к языку программирования. И для этого в среде разработчика в меню Project есть специальная команда Add COM Wrapper. Вызовем ее и увидим, что в списке компонент COM есть и творение наших рук. Нужно только отметить его галочкой (рис. 6).
Рис. 3.6.
В результате будет сгенерирован новый пакет com_object, названный так по имени проекта, в котором COM-объект создавался. В этом пакете есть пара новых файлов. Вот первый из них (класс CoMirPK), являющийся шлюзом к двоичному коду компоненты:
package com_object;
import com.ms.com.*;
import com.ms.com.IUnknown;
import com.ms.com.Variant;
/** @com.class(classid=C0038C80-C7ED-4D8E-9E18-C90AA7EF1C67,
DynamicCasts)
@com.interface(iid=1127D7AF-52C0-4547-8C7D-4E492C5130D2,
thread=AUTO, type=DISPATCH) */
public class CoMirPK implements IUnknown,com.ms.com.
NoAutoScripting,com_object.CoMirPK_Dispatch
{
/** @com.method(dispid=100, type=METHOD, name=”wait”,
returntype=VOID)
@com.parameters([in,out,elementType=VARIANT,type=PTR]
Parameter0, [in,out,elementType=VARIANT,type=PTR]
Parameter1, [type=VARIANT] return) */
public native Variant wait(Variant Parameter0, Variant
Parameter1);
/** @com.method(dispid=101, type=METHOD, name=”runWord”,
returntype=VOID)
@com.parameters([in,type=STRING] Parameter0) */
public native void runWord(String Parameter0);
// hashCode UNMAPPABLE: Name is a keyword or conflicts
with another member.
// public native int hashCode();
// toString UNMAPPABLE: Name is a keyword or conflicts
with another member.
// public native String toString();
// equals UNMAPPABLE: Name is a keyword or conflicts
with another member.
// public native boolean equals(Object Parameter0);
/** @com.method(dispid=105, type=METHOD, name=”userLogOff”,
returntype=VOID)
@com.parameters() */
public native void userLogOff();
// notify UNMAPPABLE: Name is a keyword or conflicts
with another member.
// public native void notify();
// getClass UNMAPPABLE: Name is a keyword or conflicts
with another member.
// public native Object getClass();
// notifyAll UNMAPPABLE: Name is a keyword or conflicts
with another member.
// public native void notifyAll();
public static final com.ms.com._Guid iid = new com.ms.com.
_Guid((int)0x1127d7af, (short)0x52c0, (short)0x4547,
(byte)0x8c, (byte)0x7d, (byte)0x4e, (byte)0x49,
(byte)0x2c, (byte)0x51, (byte)0x30, (byte)0xd2);
public static final com.ms.com._Guid clsid = new com.ms.com.
_Guid((int)0xc0038c80, (short)0xc7ed, (short)0x4d8e,
(byte)0x9e, (byte)0x18, (byte)0xc9, (byte)0xa,
(byte)0xa7, (byte)0xef, (byte)0x1c, (byte)0x67);
}
Второй интерфейс, CoMirPK_Dispatch, нужен для установки связи посредством автоматизации OLE и поддерживает вызов методов компоненты с помощью интерфейса IDispatch, за что и получил свое имя:
package com_object;
import com.ms.com.*;
import com.ms.com.IUnknown;
import com.ms.com.Variant;
// Dispatch-only interface CoMirPK_Dispatch
/** @com.interface(iid=1127D7AF-52C0-4547-8C7D-4E492C5130D2,
thread=AUTO, type=DISPATCH) */
public interface CoMirPK_Dispatch extends IUnknown
{
/** @com.method(dispid=100, type=METHOD, name=”wait”,
returntype=VOID)
@com.parameters([in,out,elementType=VARIANT,type=PTR]
Parameter0, [in,out,elementType=VARIANT,type=PTR]
Parameter1, [type=VARIANT] return) */
public Variant wait(Variant Parameter0, Variant
Parameter1);
/** @com.method(dispid=101, type=METHOD, name=”runWord”,
returntype=VOID)
@com.parameters([in,type=STRING] Parameter0) */
public void runWord(String Parameter0);
/** @com.method(dispid=105, type=METHOD, name=”userLogOff”,
returntype=VOID)
@com.parameters() */
public void userLogOff();
public static final com.ms.com._Guid iid = new com.ms.com.
_Guid((int)0x1127d7af, (short)0x52c0, (short)0x4547,
(byte)0x8c, (byte)0x7d, (byte)0x4e, (byte)0x49,
(byte)0x2c, (byte)0x51, (byte)0x30, (byte)0xd2);
}
Директивы, начинающиеся с @com, описывают мета-информацию о компоненте, взятую из библиотеки типов: числовой идентификатор метода, его параметры, имя и т. д.
Программа, которая использует COM-компоненту, обязательно должна содержать строку импорта всех классов пакета com_object:
import com_object.*;
Одно из полей класса программы описывает ссылку на интерфейс автоматизации:
. . .
CoMirPK_Dispatch component;
. . .
а значение присваивается ей внутри конструктора класса:
. . .
// TODO: Add any constructor code after initForm call
component = new CoMirPK();
. . .
Теперь перейдем к обработчикам, из которых вызываются методы COM-объекта. Тот, что вызывается в ответ на нажатие кнопки «Запустить Word», выглядит следующим образом:
private void button1_click(Object source, Event e)
{
// Запустить Word
component.runWord(null);
}
Приведем исходный текст обработчика нажатия кнопки «Закончить сеанс Windows»:
private void button2_click(Object source, Event e)
{
// Закончить сеанс Windows
component.userLogOff();
}
Попробуйте готовую тестовую программу в деле. Заодно испытайте компоненту в других средах, например, в Borland C++Builder.