|
《关于VisiBroker For Delphi的使用》(3)
-CORBA技术实践(一) 数据挖掘交友
宜昌市中心人民医院 赵普昉 数据挖掘实验室
email: 3boy@sohu.com 数据挖掘研究院
数据挖掘研究院
3,数组对象与简单数据对象的传递 数据挖掘交友
前面提到了一些较为简单的数据操作,我们都可以想象一下,如果操作CORBA对象与操作C/S结构的数据对象一样的方便,那么CORBA又有什么神奇了,不知道看过李维的分布式多层应用系统的书籍时,是否留意到李维对CORBA的评价,无论你看过 数据挖掘研究院
还是没有看过,我都要告诉正在使用CORBA编程的朋友们,CORBA比COM/COM+简单,而CORBA的跨平台特性,以及与COM/COM+同样的负载平衡能力,足以让我们将这项分布式技术应用到应用体系的设计之中,其实对于使用Borland的产品开发分布式系统无论你采用CORBA或是COM/COM+其实最核心的技术就是MIDAS,因为
你总可以在CORBA/COM/COM+中看到MIDAS的影子,所以我建议无论你是准备学习CORBA还是学习COM/COM+最好先学习一下MIDAS,本文不涉及MIDAS,关于MIDAS请看李维的《Delphi5.X分布式多层应用—系统篇》。
为什么我从开始就一直要大家使用文本编辑器之类的东西书写IDL,而不用TypeLibrary 数据挖掘工具
来书写IDL,其实我觉得只是为了让刚刚接触CORBA的程序员获得一些更多的IDL方面的知识罢了,在实际的开发中你可以完全很方便的使用TypeLibrary来编写接口规则。 数据挖掘论坛
下面我简要的列举几类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 <long> UnboundeSeq; 数据挖掘论坛
typedef sequence <long,42> 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);
for I := 0 to PoolSize - 1 do
begin 数据挖掘交友
FModules[I].InUse := False;
FModules[I].Module := FModuleClass.Create(Application); 数据挖掘工具
end; 数据挖掘工具
end; 数据挖掘研究院
for I := 0 to Length(FModules) - 1 do 数据挖掘实验室
if not FModules[I].InUse then 数据挖掘研究院
begin 数据挖掘论坛
FModules[I].InUse := True; 数据挖掘交友
Result := FModules[I].Module; 数据挖掘交友
Break; 数据挖掘实验室
end; 数据挖掘研究院
finally 数据挖掘研究院
FCSect.Leave; 数据挖掘研究院
end; 数据挖掘论坛
//检查曾经是否连接 数据挖掘工具
if not Assigned(Result) then 数据挖掘论坛
raise Exception.Create("Pool is out of capacity"); 数据挖掘实验室
end;
initialization
ModulePooler := TModulePooler.Create; 数据挖掘交友
数据挖掘工具
finalization
ModulePooler.Free; 数据挖掘研究院
end. 数据挖掘工具
//
|