下面我简要的列举几类IDL书写的事例与利用IDL2PAS生成的PASCAL代码。
1、常量的定义
/**IDL书写**/
module MyCRB{
const long iMyConst=1;
interface myFace {
const long iiMyConst=2;
};
};
/**Pascal**/
unit MyCRB_I;
interface
uses Corba;
const
iMyCOnst:integer=1;
myFace_iiMyConst=2;
2、不在接口中申明的常量
/**IDL**/
module MyCRB{
const long myconst=1;
};
/*pascal*/
unit MyCRB_I;
interface
const myconst:integer=1;
3、枚举类型
/*IDL*/
enum MyCRBKind{A,B,C,D,……..}
/*pascal*/
myCRBkind=(A,B,C,D……..);
4、结构体
/*IDL*/
struct mystructtype{
long X;
string Y;
boolean Z;
};
/*pascal*/
//XXX_I.pas
type mystructtype=interface;
//XXX_C.pas
mystructtype=interface
function _get_X:integer;
function _get_Y:string;
function _get_Z:boolean;
procedure _set_X(const Value:integer);
procedure _set_Y(const Value:string);
procedure _set_Z(const Value:boolean);
property X:integer read _get_X write _Set_X;
property Y:string read _get_Y write _Set_Y;
property Z:boolean read _get_Z write _Set_Z;
…….
还有太多的代码,自己创建一个看一下,为了节约篇幅我就不做详细的翻译了
下面请大家试一下以下的申明会生成什么样的Pascal代码
5、联合体
union un_exp switch(long)
{
case 1:long x;
case 2:string y;
case 3:st_exp Z;
};
6、sequence(我理解为动态数组)
typedef sequence UnboundeSeq;
typedef sequence ShortBoundSeq
7、数组
const long ArrayBound=10;
typedef long longArray[ArrayBound];
8、抽象接口
module exp{
interface myface{
long op(in string s);
};
};
9、多重继承
module M{
interface A{
void A1();
void A2();
};
interface B{
void B1();
void B2();
};
interface AB:B,A{
void AB1()
void AB2();
};
};
10、交叉模型定义
module m1{
interface if1;
module m2{
interface if2{
m1::if1 getIf1();
};
interface if1{
m2::if2 getif2()
};
};
};
以上我介绍了一些数据的定义规范,然而我们需要不仅仅是这样的一些比较抽象的接口定义法则,我们要将法则应用到实际的开发中去,那么我们又是如何运用这些法则了,对于接口描述语言的翻译我前面讲到直接使用IDL2PAS就不讲了,以后的章节中也不会在去将如何转换的问题。下面我们实践一下: 编写接口定义一个返回为浮点类型,输入为短整型变量数组对象的方法
typedef short ArrayType[3];
//自定义类型定义长度为3的数组
interface Account {
float InputArray(in ArrayType myArray);//输入为整形数组,返回类型为float的方法
};
//服务端程序的处理xxx_impl.pas
interface
uses
SysUtils,
CORBA,
account_i,
account_c;
type
TAccount = class;
TAccount = class(TInterfacedObject, account_i.Account)
protected
//******************
public
constructor Create;
function InputArray ( const myArray : account_i.ArrayType): Single;
end;
implementation
uses ServerMain;
constructor TAccount.Create;
begin
inherited;
end;
function TAccount. InputArray (const myArray : account_i.ArrayType): Single;
var
j: Integer;
begin
// account_i.ArrayType是指我们自定义的数组类型在account_I单元中
for j := 0 to 2 do
begin
Form1.Memo1.Lines.Add('myArray[' + IntToStr(j) + '] = ' + IntToStr(myArray[j]) );
//接受从客户端传递过来的数组变量并将其依次加入到主窗体的MEMO中
end;
result := random * 100;//返回一个随机数
end;
initialization
randomize;
end.
//服务端程序主单元
unit ServerMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Corba,
Account_I, Account_C, Account_S, Account_Impl, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
private
{ private declarations }
protected
{ protected declarations }
Acct : Account; // skeleton 对象
procedure InitCorba;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.InitCorba;
begin
CorbaInitialize;
// Add CORBA server Code Here
Acct := TAccountSkeleton.Create('Array Server', TAccount.Create);
BOA.ObjIsReady(Acct as _Object);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
InitCorba;
Memo1.Lines.Add('Account object created...');
Memo1.Lines.Add('Server is ready');
end;
end.
//客户端程序
unit ClientMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Corba, StdCtrls, Account_I, Account_C;
type
TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ private declarations }
protected
{ protected declarations }
Acct : Account;
myArray : ArrayType;
procedure InitCorba;
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.InitCorba;
begin
CorbaInitialize;
Acct := TAccountHelper.bind;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
j: Integer;
begin
InitCorba;
for j := 0 to 2 do
myArray[j] := (j + 1) * 100;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := FormatFloat('InputArray = $#,##0.00', Acct.inputArray(myArray));
end;
end.
上面的程序实例很简单我就不一一说明了,下面我们来看一个数据访问的实例
//IDL
interface Employee {
any getEmployeesByName(in string name);
}; 接口方法声明单元
//XXX_Impl.pas
interface
uses
SysUtils,
CORBA,
employee_i,
employee_c;
type
TEmployee = class;
TEmployee = class(TInterfacedObject, employee_i.Employee)
public
constructor Create;
function getEmployeesByName ( const name : AnsiString): ANY;
end;
implementation
uses dmEmployee,DMPooler, provider,DSIntf,ServerMain;
constructor TEmployee.Create;
begin
inherited;
end;
function TEmployee.getEmployeesByName ( const name : AnsiString): ANY;
var
DM: TdmEmploy;
RecsOut: Integer;
Options: TGetRecordOptions;
begin
Options := [grMetaData,grReset]; //must specify meta data
DM := ModulePooler.GetModule as TdmEmploy; //Get instance of datamodule from Pool
try
DM.qryEmployee.Close;
DM.qryEmployee.ParamByName('name').AsString:= name + '%';
//显示连接服务器的数量
Inc(Form1.HitCount);
Form1.Label1.Caption := Format('Hit Count = %d', [Form1.HitCount]);
DM.qryEmployee.Open;
Result:=DM.proEmployee.GetRecords(-1, RecsOut, Byte(Options));
DM.qryEmployee.Close;
finally
ModulePooler.FreeModule(DM);//Return instance of DataModule to pool
end;
end;
initialization
//将TdmEmploy对象放入共享池中
ModulePooler.ModuleClass := TdmEmploy;
end.
//共享池的声明单元
主要描述如何提供一个多客户的访问数据提供
unit DMPooler;
interface
uses SysUtils, Classes, Forms, SyncObjs, Windows;
type
//本单元用于为每个客户提供一个独立使用的DataModule对象,相当于我们在以前的CORBA DataModule中选择创建的多线程对象一样的功能
TDataModuleClass = class of TDataModule; //定义类
TPooledModule = record//声明记录类型
Module: TDataModule; //继承标准的TdataModule
InUse: Boolean; //标明上面继承的TdataModule是否在使用
end;
TModulePooler = class
private
FCSect: TCriticalSection; //允许线程自己改变FModules
FModuleClass: TDataModuleClass; //在共享池中类化TDataModule
FModules: array of TPooledModule; //定义一个动态的对象记录数组
FSemaphore: THandle; //限定同时使用的用户规则
public
property ModuleClass: TDataModuleClass read FModuleClass write FModuleClass;
constructor Create;
destructor Destroy; override;
function GetModule: TDataModule;
procedure FreeModule(DataModule: TDataModule);
end;
const
PoolSize = 5;
var
ModulePooler: TModulePooler = nil;
implementation
uses Dialogs;
{ TModulePool }
constructor TModulePooler.Create;
begin
IsMultiThread := True;
FCSect := TCriticalSection.Create;
FSemaphore := CreateSemaphore(nil, PoolSize, PoolSize, nil);
end;
destructor TModulePooler.Destroy;
begin
FCSect.Free;
CloseHandle(FSemaphore);
end;
procedure TModulePooler.FreeModule(DataModule: TDataModule);
var
I: Integer;
begin
FCSect.Enter;
try
for I := 0 to Length(FModules) - 1 do
if FModules[I].Module = DataModule then
FModules[I].InUse := False;
ReleaseSemaphore(FSemaphore, 1, nil);
finally
FCSect.Leave;
end;
end;
function TModulePooler.GetModule: TDataModule;
var
I: Integer;
begin
Result := nil;
if WaitForSingleObject(FSemaphore, 5000) = WAIT_TIMEOUT then
raise Exception.Create('Server too busy');
FCSect.Enter;
try
if Length(FModules) = 0 then
begin
SetLength(FModules, PoolSize);
[1] [2] 下一页 [系统软件]InstallShield Express for delphi制作安装程序定… [系统软件](转帖) 忘记登录密码的解决方案 for XP/2003/2000 [系统软件]交叉编译sshd for IXP425 ARM Platform by MVL 3… [Delphi程序]《关于VisiBroker For Delphi的使用》(4) [Delphi程序]一个超链接Image控件!(For D3,D4,D5,D6)源代码 [Delphi程序]Five of the best tools for Delphi [Delphi程序]《关于VisiBroker For Delphi的使用》(3) [Delphi程序]《关于VisiBroker For Delphi的使用》(2) [Delphi程序]《关于VisiBroker For Delphi的使用》 [Delphi程序]Delphi for .Net 编译器预览 - by John Kaster
|