Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
HOR / TOTAL.DOC
Скачиваний:
3
Добавлен:
16.04.2013
Размер:
312.83 Кб
Скачать

7. Пример программы, работающей с распределенными объектами.

В этой главе будет приведен пример полного цикла разработки программы, работающей с системой и созданной с помощью интегрированной среды разработки Delphi.

7.1. Последовательность действий при создании объекта.

Этапы, которые должен пройти разработчик при создании приложения, работающего с распределенными объектами в среде Delphi включают в себя следующие пункты, показанные на листе6.

Для разработки сервера объекта:

  1. Разработка реализации объекта как компонента Delphi.

  2. Создание производного от этого нового класса с помощью программы-эксперта Delphi.

  3. Замена ссылок на исходный объект ссылками на новый и перекомпиляция программы.

Для разработки клиента объекта:

  1. Создание с помощью другого эксперта кода для объекта - представителя удаленной реализации на клиенте.

  2. Включение полученного объекта в программу.

Далее будет описан пример создания системы удаленного управления библиотекой.

7.2. Объект библиотека.

В качестве примера возьмем объект, который будет моделировать библиотеку. Он будет способен сохранять списки книг и их авторов. Также имеются методы для определения общего количества книг и по номеру книги возвращать ее название и автора. Часть определения данного класса показана ниже (методы, предназначенные для обеспечения внутреннего функционирования, не показаны):

type

TLibrary = class(TComponent)

...

automated

procedureAddBook(constTitle, Author:string);

function BookInfo(Index: Integer;

var Author: string): string;

published

propertyCount: IntegerreadFCount;

end;

Ключевое слово automated означает, что компилятор будет создавать для таких методов таблицу с описанием типов их параметров, что позволяет во время выполнения программы или запуска эксперта определить эти параметры и создать правильный программный код. Изначально эта возможность предназначалась для поддержки технологииOLE Automation, но может быть использовано и для других целей.

7.3. Сервер объекта.

После того как объект создан и оттестирован, запускается эксперт, который создает новый модуль и новый компонент. По умолчанию к имени объекта добавляется префикс E, который означает экспортирование (Export) объекта. Часть объявления нового классаTELibrary показана ниже.

type

TELibrary = class(TLibrary)

private

procedure _AddBook;

procedure _BookInfo;

procedure __Get_Count;

procedure__Unhandled(Caller: TConnectThread;

RequestHeader: TRequestHeader;

var ReplyHeader: TReplyHeader);

end;

Новый метод __Unhandled будет вызван системой для любого запроса к объекту. Идеология подключения объектов, написанных наObject Pascal такова. Для каждой заявленной операции пишется метод который имеет имя, совпадающее с именем операции. Для методов, осуществляющих чтение и запись свойств объявляются методы с префиксами‘_Get_’ и‘_Set_’. Если указанный метод не найден, то система пытается найти метод__Unhandled и вызывает его. Таким образом, можно самостоятельно запрограммировать всю требуемую логику. Эксперт всегда создает метод__Unhandled, который обрабатывает переданный ему параметры и осуществляет вызов методаSynchronize у параметраCaller. Это нужно для вызова метода из основного потока программы, так какVCL (Visual Component Library), используемая вDelphi не допускает одновременное использование ее из нескольких потоков. Этот алгоритм кодируется таким образом:

procedureTELibrary.__Unhandled(Caller: TConnectThread;

RequestHeader: TRequestHeader;

var ReplyHeader: TReplyHeader);');

var

Method: TThreadMethod;

begin

FRequestHeader := RequestHeader;

FReplyHeader := TReplyHeader.Create;

FReplyHeader.ReplyStatus := NO_EXCEPTION;

TMethod(Method).Data := Self;

TMethod(Method).Code :=

MethodAddress(‘_’+RequestHeader.Operation);

try

if TMethod(Method).Code <> nil

then Caller.Synchronize(Method);

except

FReplyHeader.ReplyStatus := SYSTEM_EXCEPTION;

FReplyHeader.Body.PutString(

IDL:omg.org/CORBA/SystemException:1.0’);

end;

ReplyHeader := FReplyHeader;

end;

А каждый и методов _AddBook, _BookInfo и__Get_Count просто декодирует переданные параметры, вызывает реализацию метода или свойства и кодирует полученный результат. Например, метод_BookInfo реализован следующим образом:

procedureTELibrary._BookInfo;

var

Param1: Integer;

Param2: string;

Result: string;

begin

FRequestHeader.Body.GetLong(Param1).GetString(Param2);

Result := inherited BookInfo(Param1, Param2);

FReplyHeader.Body.PutString(Result).PutString(Param2);

end;

Следует отметить, что параметр Author был определен экспертом как типаinout, вместо более логичного, и реально являющегося типаout. Это связано с тем, что в языкеPascal нельзя явно указать параметр, который только возвращается из процедуры. Также имена параметровIndex иAuthor заменены наParam1 иParam2 - эксперт не может получить имена параметров, только общее количество и тип каждого параметра.

После этого остается заменить в тесте ссылки на компонент TLibrary ссылками на новый компонентTELibrary, а также добавить еще два кусочка кода - один для инициализации системы, другой для благополучного завершения выполнения.

procedureTLibForm.FormCreate(Sender: TObject);

var

Impl: ImplementationDef;

begin

Impl := ImplementationDef.Create;

Impl.InterfaceName := 'Library';

LibFormORB:= ORB.ORBInit([nil],'');

LibFormBOA:=LibFormORB.BOAInit([nil],'');

LibFormBOA.ObjIsReady(Library1, Impl);

Impl.Release;

end;

procedureTLibForm.FormDestroy(Sender: TObject);

begin

LibFormBOA.DeactivateObj(Library1);

LibFormBOA.Release;

LibFormORB.Release;

end;

Соседние файлы в папке HOR