Midas的三種調用遠程方法的方式
1.晚綁定
//使用 Late Binding
…
DCOMConnection1.AppServer.GetSystemInfo(vTime, vRDM, vThread);
藉 由 TDCOMConnection( 或 是 TSocketConnection ,
TCORBAConnection)的 AppServer 特性取得遠端應用程式伺服器,再呼叫其中
的 GetSystemInfo 方法。這種方式可以正確的呼叫到遠端應用程式伺服器之中
提供的服務。但是你必須知道的是 AppServer 特性回傳的是一個 Variant 型態
的變數,當程式透過 Variant 呼叫遠端方法時,Delphi 會以 IDispatch 介面動態
的和遠端應用程式伺服器溝通,組合呼叫方法和參數,最後再進行呼叫。所以
這種呼叫方式需要執行非常多額外的工作,因此並不是很有效率。只是因為
TDCOMConnection 元件直接提供了 AppServer 這個特性可以讓軟體人員很方
便的呼叫遠端方法,所以幾乎所有的人都是使用這種方式(當然也包括懶惰的
我在內)。
2.早綁定
最有效率的遠端呼叫方式-Early Binding
使用 Early Binding 的好處是 Delphi 在編譯應
用程式時便可以檢查程式師使用的語法是不是正確,傳遞的參數形態是不是正
確,以及編譯器可以事先便產生所有必要的執行碼,因此不需要應用程式執行
時再使用動態方式和遠端應用程式伺服器溝通,所以在執行效率上比起使用 所以在執行效率上比起使用 所以在執行效率上比起使用 所以在執行效率上比起使用Late Binding 更有效率,也更安全。
//使用 Early Binding
…
begin
(DCOMConnection1.GetServer as IrdmDemo3).GetSystemInfo(vTime,
vRDM, vThread);
…
end;
需要在用戶端應用程式啟動時,
載入應用程式伺服器的 Type Library 並且註冊它,之後就可以使用 Early
Binding 的方式呼叫遠端方法了。例如在這個範例中我於表格的 OnCreate 事件
處理函式中加入了如下的程式碼:
procedure TForm2.FormCreate(Sender: TObject);
begin
OleCheck(LoadTypeLib('puperserver.tlb', servertlb));
end;
LoadTypeLib 可以載入指定的 Type Library 並且註冊它。因此你可以把所
有需要以 Early Binding 存取的應用程式伺服器的 Type Library 檔案(.tlb 的檔案)
拷貝到用戶端機器的特定目錄之下,例如 C:/AppServerTLB,然後使用
OleCheck(LoadTypeLib('c:/AppServerTlb/puperserver.tlb', servertlb)); 的程式碼載入指定的Type Library。
使用 Early Binding 雖然可以大幅增加遠端呼叫的執行效率,但是天下沒
有白吃的午餐,當你使用視覺化Type Library 編輯器異動應用程式伺服器介面
時,例如增加其中的方法,或是修改其中的參數,那麼你必須重新拷貝這個
Type Library 到用戶端機器的 C:/AppServerTLB 目錄之下,否則用戶端的Type
Library 和應用程式伺服器的服務就不一致了。當然你也可以把所有的 Type
Library 檔案拷貝到網路的全域目錄之下,然後讓用戶端都從這個目錄中載入
Type Library,如此就可以保證用戶端應用程式能夠取得最新的 Type Library
的資訊了。另外 Early Binding 有一個限制,那就是它只能使用在 DCOM 的通訊協定之中。
Early Binding的方式雖然很有效率,但可惜的是不是所有的多層應用系統
都可以使用它。例如如果你是使用 Socket 通訊協定的話,就無法使用 Early
Binding。
3.DISPATCH TABLE
比 Late Binding 更有效率。
在Delphi 中使用視覺化 Type Library 編
輯器定義應用程式伺服器的服務後,Delphi 便會在 Type library 的 wrapper 類別中自動產生 Dispatch Table 的介面。你可以在Delphi 中開啟應用程式伺服器的 wrapper 類別原始程式(通常是 XXX_TLB.PAS 這個檔案,XXX 代表你的應用程式伺服器的名稱),在 wrapper 類別中會有一個以 disp 結尾的介面,這個介面就是應用程式伺服器的 Dispatch Table。
IrdmDemo3Disp = dispinterface
['{AFC25B93-37E0-11D3-AA94-0080C8518D04}']
例如在下面的程式碼中首先宣告一個 IrdmDemo3Disp 的變數 aDisp,然
後把 TDCOMConnection 的 AppServer 特性先轉換為 IDispatch,再轉換為
IrdmDemo3Disp 介面,再指定給 aDisp 變數,最後就可以使用這個變數呼叫遠
端方法了。
//使用 Dispatch Interface
var
aDisp : IrdmDemo3Disp;
begin
…
begin
aDisp := IrdmDemo3Disp(IDispatch(DCOMConnection1.AppServer));
aDisp.GetSystemInfo(vTime, vRDM, vThread);
…
end;
…
end;
由於 Dispatch Table 介面可以由視覺化 Type Library 編輯器自動產生,而
且又能夠使用同時使用在 DCOM 和 Socket 通訊協定之中,因此如果你不想像
上一小節討論的一樣在用戶端分發應用程式伺服器的 Type Library,那麼你就
可以考慮使用 Dispatch Table 的呼叫方式,因為它幾乎和 Late Binding 一樣很方便,而且在執行效率上是比 Late Binding 來得良好。