- •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.1. Cоздание сервера com
Прежде всего воспользуемся вызовом мастера COM DLL, расположенного на закладке New•Components (она появляется при вызове команды File•New Project среды разработчика Visual J++). Для лучшего понимания рассмотрим сквозной пример COM-объекта, один метод которого запускает текстовый процессор Word, а другой завершает текущий сеанс Windows (аналог команды Log off). Сначала мне хотелось делать полный рестарт операционной системы, но, попробовав, я решил, что это слишком расточительно в плане расходования времени.

Рис. 3.1.
Итак, создадим проект с именем COM_Object (рис. 1), внутри которого находится пустой класс-заготовка для будущего объекта. Хорошо бы, конечно, заменить его имя чем-то существенным, например CoMirPK. Для этого в окне проекта нужно щелкнуть на файле компоненты правой кнопкой мыши и выбрать команду переименования Rename. Несомненная неудача среды разработчика в том, что при смене имени файла не меняется название класса. Следовательно, это надо сделать самостоятельно. Зато внутри комментариев, которые видны в теле класса, имеется заготовка метода onCOMRegister(). Вы можете раскрыть ее и поместить внутрь код, вызываемый каждый раз при регистрации создаваемой компоненты в системе, и наоборот, при «выковыривании» из нее (рис. 2).

Рис. 3.2.
Для каждого из двух методов создадим отдельный интерфейс, чтобы максимально использовать инструментарий среды, а планируемые действия занесем в список TaskList — эдакий электронный планировщик.
Сначала создадим первый интерфейс IRunWord2000, исходный текст которого весьма мал:
public interface IRunWord2000
{
/**
* Этот метод запускает текстовый процессор MS Word 2000
*/
public abstract void runWord(String path);
}
Следом за ним нужно описать интерфейс ILogOff, также состоящий всего из нескольких строчек:
public interface ILogOff
{
/**
* Данный метод ”выгружает” текущего пользователя
*/
public abstract void userLogOff();
}
Впрочем, малый размер позволяет описать их вручную. Однако полезно потренироваться, поэтому правой кнопкой мыши щелкаем на имени проекта в окне Project Explorer и из контекстного меню выбираем Add• AddClass•Interface (рис. 3).

Рис. 3.3.
Сам же класс компоненты должен реализовать методы этих интерфейсов:
public final class CoMirPK implements IRunWord2000, IlogOff
Когда имена их добавлены в описание класса, в окне Class Outline внутри структуры класса CoMirPK нужно найти папку с названием Implemented Interfaces. Вы увидите два значка интерфейсов, которые наш компонент реализует. Чтобы избежать лишней работы, щелкните на одном из них и выберите из контекстного меню команду Add Method Stubs. Благодаря ей в описании класса появится заготовка метода наследуемого интерфейса. Это и легче, чем ручное написание, и лучше с точки зрения защиты от ошибок. Повторите эти действия и для другого интерфейса.
В своей работе мы будем пользоваться вызовом программного интерфейса Win32, поэтому с помощью технологии J/Direct необходимо импортировать точку входа в искомую функцию ExitWindowsEx(). На линейке инструментов имеется специальный список полезных штучек Task List. Запустим из него команду J/Direct Call Builder, найдем в списке ExitWindowsEx() и нажмем кнопку Copy To Target (рис. 4).
В проекте появится новый класс-утилита Win32:

Рис 3.4.
public class Win32
{
/**
* @dll.import(”USER32”,auto)
*/
public static native boolean ExitWindowsEx(int uFlags,
int dwReserved);
}
Внутри комментария к методу вы видите специальную директиву @dll.import, заставляющую виртуальную машину Java импортировать вызываемый метод из библиотеки USER32.
Остается дописать класс CoMirPK до «кондиционного» вида:
import com.ms.com.*;
import java.io.IOException;
/**
* This class is designed to be packaged with a COM DLL
output format.
* The class has no standard entry points, other than the
constructor.
* Public methods will be exposed as methods on the default
COM interface.
* @com.register (clsid=C0038C80-C7ED-4D8E-9E18-C90AA7EF1C67,
typelib=B343C87E-A9B5-43D0-9787-D56D4F962EAF)
*/
public final class CoMirPK implements IRunWord2000, ILogOff
{
// TODO: Add additional methods and code here
/**
* NOTE: To add auto-registration code, refer to the
documentation
* on the following method
* public static void onCOMRegister(boolean unRegister) {}
*/
public void runWord(String path)
{
String commandLine =
”c:\\Program Files\\Microsoft Office\\Office\\
WINWORD.EXE”;
if(path != null) commandLine = path;
try
{
Runtime.getRuntime().exec(commandLine);
}catch (IOException e)
{
com.ms.wfc.ui.MessageBox.show(
”Не могу запустить Word!”, ”COM_Object”);
}
}
public void userLogOff()
{
Win32.ExitWindowsEx(0,0);
}
}
Уникальный идентификатор COM-класса задается директивой @com.register, расположенной непосредственно перед самым описанием класса компоненты. Директива import java.io.IOException нужна для вызова метода getRuntime().
Метод, вызывающий текстовый процессор Word, первоначально задает путь к Word 2000, так как он устанавливается по умолчанию. Тем не менее можно назначить альтернативный маршрут с помощью единственного параметра. При установке Word по умолчанию через этот параметр передается значение null. Дальше специальный класс-утилита Runtime вызовами getRuntime() и exec() запускает программу winword.exe, что и требуется.
Метод перезапуска Windows включает в себя единственную строчку, в которой происходит вызов функции API ExitWindowsEx() с нулевыми параметрами, говорящими о том, что нужно лишь завершить текущий сеанс Windows. При другом значении первого параметра может произойти полная перезагрузка. Второй параметр всегда равен 0.
Примечание.Перед компиляцией загляните в опции проекта и найдите закладку COM Classes. Там вы сможете указать, какие классы вы хотите сделать объектами COM, а заодно установить некоторые опции создаваемой библиотеке типов (рис. 5).

Рис. 3.5.
