名詞解釋:
OLE: (Object linking and embedding對象的鏈接與嵌入)
使得服務器模塊和客戶模塊通過標准的接口進行通訊。兩個模塊可以在同一台計算機或位於不同的計算機上,位置對用戶來說是無關緊要的。服務器模塊實現了一組接口,客戶模塊通過這組接口進行通訊。
COM: (Component object modal組件對象模型)
實現了OLE的功能,具體可完成一下功能:
l 編寫供多種語言使用的代碼;
多種語言:指的是建立好的COM組件不在乎訪問它的編程語言,任何一種編程語言只要知道COM組件的接口,訪問是都能完成同樣的功能。
l 創建ActiveX控件;
l 通過OLE Automation操縱其他應用程序;
如:Microsoft Excel的OLE編程接口,創建對象後,任何一種程序都可以實現對Excel的操作。
l 與其他計算機上的應用程序通訊;
實際為COM接口與接口之間的通訊,因其實現了不同語言、不同計算機的方式,所以實現不同計算機上應用程序的通訊也就十分容易。
COM模塊:
COM的模塊指獨立的應用程序(EXE)或者動態連接庫(DLL),在實現COM時,采用DLL方式要比較容易一些。因為:應用程序在加載時在內存中都是獨立的地址控件,而DLL加載後可以駐留內存。當多個客戶端調用COM時,如果采用EXE形式,就會有多個EXE被加載,而且COM處理客戶端的訪問時,也必須在不同的地址空間來回切換,大費周張。而DLL形式永遠只有一個駐留內存,COM只要在相同的內存空間中尋找執行代碼即可。
逐步深入:
DLL我們都已經寫了很多,通常我們寫的DLL都是定義的一些方法或是過程來實現特定的操作,當然定義的出口(Exports)也就是這些方法或是過程。現在我們來寫一個出口為一個類的DLL來展開我們COM編寫的學習。
准備工作:
打開Delphi,選擇FileNewOthers,選擇DLL Wizard自動創建一個DLL工程,選擇FileNewUnit新建一個單元,全部保存。
寫代碼:
在新建的Unit中定義一個抽象類:
Type
TCalculator=Class
Public
Function Addition (Op1, Op2: Double): Double ; virtual; abstract;
End;
這個類很簡單,就定義了一個抽象方法實現兩個數的相加。
定義抽象類後,定義一個類來實現這個抽象類:
Type
TCalcImple=Class (TCalculator)
Public
Function Addition (Op1, Op2: Double): Double; Override;
End;
方法實現:
Function TCalcImple.Addition(Op1, Op2: Double): Double;
Begin
Result: =Op1+Op2;
End;
當然我們還差一個創建這個類的方法,我們在加入如下:
Function CreateCalcImple:TCalcImple;stdcall;
Begin
Result:=TCalcImple.Create;
End;
定義出口:
Exports CreateCalcImple;
這樣我們這個DLL的編寫就完成了,我問再來寫一個Exe程序來調用它。具體在此就不再操作以便,一些列出Exe的源代碼:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
{定義與DLL中定義的抽象類一樣的類,類名稱可以自定}
Type
TCalculator=Class
Public
Function Addition(Op1,Op2:Double):Double;virtual;abstract;
End;
type
TForm1 = class (TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
v_Obj:TCalculator;
end;
{靜態調用DLL,注意返回類型與DLL中的不同,為抽象類的名稱必須與DLL中的一致}
Function CreateCalcImple:TCalculator;stdcall;External 'ComDLL.dll';
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
v_Obj:=CreateCalcImple;
Edit3.Text:=FloatToStr(v_Obj.Addition(StrToFloat(Edit1.Text),StrToFloat(Edit2.Text)));
v_Obj.Free;
end;
end.
升華到理論:
l D L L中定義的對象只能引出抽象方法。當建立對象時, D L L向應用程序返回虛擬方法的指針表VTable。
l 在定義抽象類的時候,定義的方法為:
Function Addition(Op1,Op2:Double):Double;virtual;abstract;
後面加上abstract(抽象方法表示)的原因是因為只有抽象方法才能被引出。
l 在執行文件中,通過DLL的出口實際只創建了一個接口,但是可以像使用對象一樣來調用其方法,這就有點開始盡是於COM了。
有上面幾點引出:
1、COM的接口可以看成一個占位符,具體的實現是在接口對應的類中;就像我們定義的抽象類(TCalculator)中的Addition方法,只是一個沒有任何意義的描述符,但通過實現類(TCalcImple)中引出後便有了具體的意義;
2、COM接口的訪問必須通過其接口類進入後才能夠訪問。就如我們例子中加入CreateCalcImple方法一樣,只有建立這個接口類(Interface)後才可以訪問具體的接口。
3、也就是說,一個COM必須具備三個方面的元素:接口定義類、接口實現類、接口創建類。只要具備了這三個方面的元素就可以實現COM。
(待續…)