Главная » Delphi » Сложные типы данных IDL CORBA

0

Следующий  пример не имеет  большого практического значения, но иллюстрирует применение ряда сложных типов  данных  в файлах IDL CORBA. В листинге 19.8 пред ставлено содержимое файла  IDL для дополнительных типов данных (ADT —  Advanced Data Types).

Листинг 19.8. ADT.idl

// Файл IDL для ADT

//

// Демонстрация различных структур данных IDL

//

// использование псевдонима для строковых типов

typedef string Identifier;

enum EnumType

{

first, second, third

};

struct StructType

{

short s; long l; Identifier i;

};

const unsigned long ArraySize = 3;

typedef StructType StructArray[ArraySize];

typedef sequence<StructType> StructSequence;

interface ADT

{

void Test1(in Identifier st,

in EnumType myEnum,

inout StructType myStruct);

void Test2(out StructType myStruct,

in StructArray myStructArray,

out StructSequence myStructSeq);

};Первый тип  данных  демонстрирует использование псевдонима для преобразова ния строковых типов.  Все строки в данном  примере имеют  тип Identifier. Тип EnumType содержит три значения: first, second и third.

Тип StructType подобен записи (record) языка Pascal. Эта структура данных со

стоит   из  трех  элементов типа  short,  long и  string (преобразован в  псевдоним

Identifier). Размер  массива хранится в константе ArraySize.

В следующих двух элементах файла IDL объявляются типы, основанные на преды

дущих определениях. Массив StructArray может  состоять не более  чем из трех  эле ментов (индексация  начинается  с  нуля).  Последовательность —   это  динамический массив.  В последней конструкции typedef объявляется последовательность элемен тов типа StructType.

И, наконец, в интерфейсе ADT определены два метода:  Test1 и Test2. Парамет ры  этих  методов подобраны таким  образом, чтобы  продемонстрировать различные направления перемещения данных.  Параметры In создаются и инициализируются на стороне клиента. Параметры Out создаются и инициализируются на стороне сервера. Параметры InOut создаются и инициализируются на стороне клиента, модифициру ются  на стороне сервера и возвращаются клиенту  с новыми значениями элементов данных.

В листинге 19.9  представлено содержимое файла  интерфейса ADT_I.pas. Обра тите  внимание, что  конструкции typedef определены именно в этом  файле. Кроме того, интерфейс создается для типа StructType. Всем сложным типам соответствуют объекты языка Object  Pascal с методами get и set и одним вспомогательным классом, реализующим упаковку (маршалинг) данных в буфер CORBA.

Листинг 19.9. Файл ADT_I.pas

unit adt_i; interface uses

CORBA;

typeEnumType = (first, second, third);

const

{ (Не изменяйте значения, присвоенные этим константам.) }

ArraySize: Cardinal = 3;

type

StructType = interface;

ADT = interface;

Identifier = AnsiString;

StructArray = array[0..2] of adt_i.StructType; StructSequence = array of adt_i.StructType; StructType = interface

[‘{B4A1845D-4DB0-9B2E-A2E3-001F2D6B8C81}’]

function         _get_s: SmallInt;

procedure _set_s (const s: SmallInt);

function         _get_l: Integer;

procedure _set_l (const l: Integer);

function         _get_i: adt_i.Identifier;

procedure _set_i (const i: adt_i.Identifier);

property         s: SmallInt read _get_s write _set_s;

property         l: Integer read _get_l write _set_l;

property         i: adt_i.Identifier read _get_i write _set_i;

end;

ADT = interface

[‘{203B9E07-735F-2980-CB02-353A7C6A5B68}’]

procedure Test1 (constst: adt_i.Identifier;

const myEnum: adt_i.EnumType;

var                          myStruct: adt_i.StructType);

procedure Test2 (out         myStruct: adt_i.StructType;

const myStructArray: adt_i.StructArray;

out                          myStructSeq: adt_i.StructSequence);

end; implementation initialization end.

В листинге 19.10 представлена реализация серверной части.  При  считывании зна чений параметров метода  в файле IDL определяется направление передачи данных. Параметру out соответствует передача данных  клиенту,  а параметру  in —  передача данных на сервер.

Для  всех  параметров  out на  стороне  сервера до  возврата  результата клиенту должны  быть созданы и инициализированы соответствующие структуры  данных.  Всепараметры, определенные как  const или  var, имеют  связанные с ними  структуры данных.

Листинг 19.10. Файл реализации серверной части для ADT

unit adt_impl;

interface uses

SysUtils,

CORBA,

adt_i,

adt_c;

type

TADT = class;

TADT = class(TInterfacedObject, adt_i.ADT)

protected

{***********************************}

{*** Пользовательские переменные ***}

{***********************************}

public

constructor Create;

procedure Test1 ( const st: adt_i.Identifier;

const myEnum: adt_i.EnumType;

var                           myStruct: adt_i.StructType);

procedure Test2 ( out         myStruct: adt_i.StructType;

const myStructArray: adt_i.StructArray;

out                           myStructSeq: adt_i.StructSequence);

end; implementation uses ServerMain;

constructor TADT.Create;

begin

inherited;

end;

procedure TADT.Test1 ( const st: adt_i.Identifier;

const myEnum: adt_i.EnumType;

var                            myStruct: adt_i.StructType);

begin

Form1.Memo1.Lines.Add(‘String from Client: ‘ + st);

case myEnum of

first:         Form1.Memo1.Lines.Add(‘Enum value is "first"’);

second: Form1.Memo1.Lines.Add(‘Enum value is "second"’);

third:      Form1.Memo1.Lines.Add(‘Enum value is "third"’);end;

Form1.Memo1.Lines.Add(Format(‘myStruct.s = %d’, [myStruct.s])); Form1.Memo1.Lines.Add(Format(‘myStruct.l = %d’, [myStruct.l])); Form1.Memo1.Lines.Add(Format(‘myStruct.i = %s’, [myStruct.i]));

myStruct.s := 10;

myStruct.l := 1000;

myStruct.i := ‘This is the return string from the Server';

end;

procedure TADT.Test2 ( out     myStruct:     adt_i.StructType;

const myStructArray: adt_i.StructArray;

out                            myStructSeq:  adt_i.StructSequence);

var

k: integer;

tempSeq: StructSequence;

begin

myStruct := TStructType.Create(20, 2000,

‘Hello from the server structType Test 2′);

for k := 0 to ArraySize – 1 do

With Form1.Memo1.Lines do begin

Add(Format(‘myStructArray[%d].s = %d’,

[k, myStructArray[k].s]));

Add(Format(‘myStructArray[%d].l = %d’,

[k, myStructArray[k].l]));

Add(Format(‘myStructArray[%d].i = %s’,

[k, myStructArray[k].i]));

end;

SetLength(tempSeq, 2);

for k := 0 to 1 do

tempSeq[k] := TStructType.Create(k + 100, k + 1000,

Format(‘k = %d’, [k]));

myStructSeq := tempSeq;

end;

initialization end.

Пользовательский интерфейс клиентского приложения состоит из двух кнопок и поля memo. Каждой  кнопке соответствует один из методов проверки ADT. Результаты вызова  этих методов отображаются в поле memo. Исходный код клиентской части представлен в листинге 19.11.

Листинг 19.11. Клиентская часть ADTunit ClientMain;

interface uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,

Dialogs, Corba, adt_c, adt_i, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

Button2: TButton;

Memo1: TMemo;

procedure FormCreate(Sender: TObject);

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

private

{ Закрытые объявления }

protected

myADT: ADT;

procedure InitCorba;

{ Защищенные объявления }

public

{ Открытые объявления }

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.InitCorba;

begin

CorbaInitialize;

myADT := TADTHelper.bind;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

initCorba;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

temp: StructType;

begin

temp := TStructType.Create(50, 500,

‘This is the client struct in Test 1′);

myADT.Test1(‘Hello from the Test1 Client’, first, temp);

with Memo1.Lines do beginAdd(‘Response from server inout struc var:’); Add(Format(‘myStruct.s = %d’, [temp.s])); Add(Format(‘myStruct.l = %d’, [temp.l])); Add(Format(‘myStruct.i = %s’, [temp.i]));

end;

end;

procedure TForm1.Button2Click(Sender: TObject);

var

I: Integer;

temp: StructType;

tempSeq: StructSequence;

tempArray: StructArray;

begin

temp := TStructType.Create(0,0,’test’);

SetLength(tempSeq, 2);

for I := 0 to ArraySize -1 do

tempArray[I] := TStructType.Create(200 + I, 2000 + I,

Format(‘Stuct %d in Array’, [I]));

myADT.Test2(temp, tempArray, tempSeq);

with Memo1.Lines do begin Add(Format(‘struct.s = %d’, [temp.s]) ); Add(Format(‘struct.l = %d’, [temp.l]) ); Add(Format(‘struct.i = %s’, [temp.i]) );

end;

for I := 0 to 1 do with Memo1.Lines do begin

Add( Format(‘tempSeq[%d].s = %d’, [I, tempSeq[I].s]) );

Add( Format(‘tempSeq[%d].l = %d’, [I, tempSeq[I].l]) );

Add( Format(‘tempSeq[%d].i = %s’, [I, tempSeq[I].i]) );

end;

end;

end.Для запуска этого  приложения необходимо откомпилировать его исходный код и убедиться  в том,  что  запущен  OSAgent.  При  щелчке  на любой  из кнопок происходит обмен  данными между клиентом и сервером. Данные, принимаемые на любой  из сто рон, отображаются в поле memo.

Источник: Тейксейра, Стив, Пачеко, Ксавье.   Borland Delphi 6. Руководство разработчика. : Пер.  с англ. — М. : Издательский дом “Вильямс”, 2002. —  1120 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии