組件技術的本質COM執行個體分析一

來源:互聯網
上載者:User
COM編程

進程內COM伺服器(In-Process COM Server)

進程內的COM伺服器(In-Process Com Server)在這前已經簡單的介紹過,在此,只對一些需要明白、理解的知識點進行闡述,再進行編程可能會更好一點;同處理序伺服程式是由於它們在DLL內實現而獲得這個名稱的。因此,伺服器占擗了和使用它的應用程式一樣的地址空間(進程)。所有的進程內COM伺服器輸出四個標準函數:DllRegisterServer、DllUnregisterServer、DllGetClassObject和DllCanUnloadNow。根據字面意思,我們也已經可以感覺的出這些函數的工作都會是什麼。當然,Delphi已經為我們提供了這些函數的預設實現。因此,讀者不必自己寫代碼來實現這些函數,但應該理解他們具體是做什麼的。

² DllRegisterServer。DllRegisterServer以兩種方式自動調用。IDE的Register ActiveX Server菜單選項調用它,Windows的命令列應用程式RegSvr32.exe(或者Borland應用程式TRegSvr)也會調用它,很多情況下可以直接用Register ActiveX Server去調用,如果手動的去實現,可以寫一個.Bat檔案。無論通過那種方式調用它,DllRegisterServer用Windows註冊表來註冊COM對象。

² DllUnregisterServer。可以感覺的出來,這個函數和DllRegisterServer是作相反的工作,實際上它們就是一個相逆的過程,它移走了DllRegisterServer放在Windows註冊表中的所有條目。可以用IDE裡的 UnRegister ActiveX Server來調用這個工程。

² DllGetClassObject。DllGetClassObject負責提供給COM一個類廠,該類廠用於建立一個COM對象(在討論類廠的時候,我們也做過明確的說明)。

² DllCanUnloadNow。COM負責調用DllCanUnLoadNow來看是否可以從記憶體中卸載COM伺服器。

線程支援(Threading Support)

線程支援只適合於同處理序伺服程式,並且不適用於進程外伺服器。同處理序伺服程式可以附著在幾個的一個。同處理序伺服程式的執行緒模式被存在Windows註冊表中,具體如下:

² ……

² ……

² ……

² ……

…………

註冊伺服器(Registering the Server)

此處將不再重提如何註冊伺服器,只是簡單的說一說為什麼要進行註冊。我們都知道,普通的Dll也需要進行註冊才可以運行,而COM對象或是COM伺服器要提供給服務於Client,那麼用戶端首先要知道要沒有這個服務?如何進行這個服務的調用或是訪問,因此它會找一些有用的索引值,而客戶所找的範疇就是註冊表。由此而言,註冊的確很有必要而肯是必不可少的。

建構函式

應該明確的是,做為一個提供服務的對象或介面或是一個組件,有一步工作應該提前做,那就是構造,而構造也是初始化,並且之前我們也說過,COM對象最好派生於TcomObject類,如此一來,我們就不得不去考慮在TcomObject中定義的建構函式都調用了虛方法函數Initialize。如果需要為自己的COM對象提供初化代碼,只需要重載Initialize方法,定義如下:

Procedure Initialize ;Virtual;

將初始化代碼放在Initialize中而不是建構函式中的原因是:Delphi中的COM對象的基類包含了一系列的非虛建構函式。根擗需要,類廠獎在不同的執行個體中調用不同的建構函式。而Initialize是虛方法,並且是唯一可以在調用時不考慮哪個建構函式是用於建立COM對象的方法。

建立一個進程內COM對象的執行個體

當使用者需要在自己的客戶程式碼中建立一個COM對象,一般會調用CreateConObject函數,該函數在ComObj.pas中定義,聲明如下:

Function CreateComObject(const ClassID:TGUID):IunKnown;

CreateComObject將要建立的COM對象的GUID作為一個參數,並返回該COM對象的IunKnown指標。苦所請求的GUID在Windows註冊表中找不到的話,將會拋出一個異常。那麼我們一起來分析一下CreateComObject函數的實現如下:

function CreateComObject(const ClassID: TGUID): IUnknown;

begin

OleCheck(CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or

CLSCTX_LOCAL_SERVER, IUnknown, Result));

end;

之前我們曾討論過OleCheck,現在將重點的精力放在CoCreateInstance上邊。如果根蹤CoCreateInstance會發現如下資訊:

function CoCreateInstance; external ole32 name 'CoCreateInstance';

因此可以這樣認為,CreateComObject函數所作的只是調用了一下Windows的函數CoCreateInstance,並提供了一些預設的參數

CoCreateInstance主要有五個參數:

Clsid:Clsid是我們想要建立的COM伺服器的GUID。這是我們專們傳遞給CreateComObject唯一的一個參數。

UnkOuter:只有在此COM對象是集合的一部分時才使用它。

DwClsContext:dwClsContext決定了讀者想要建立的類型。CreateCOMObject自動要求建立一個同處理序伺服程式(CLSCTX_INPROC_SERVER)或本地的進程外伺服器(CLSCTX_LOCAL_SERVER)。有時與此函數一起使用的另外一個標記是CLSCTX_REMOTE_SERVER。此標誌在DCOM中使用,以後將會討論。

Iid:iid是我們想要擷取一個對它的引用的介面。Delphi通常需要對IunKnown介面的應用,因為如果要其它別的引用的話,大多數類廠會失敗。Microsoft用此參數主要是為了將來的擴充。

Pv:主要是得到IunKnown介面的指標。

{一個需要註冊的是:CoCreateInstance內部建立負責建立COM對象類廠的執行個體,然後使用類廠來建立對象。建立完COM對象之後,類廠就被銷毀。顯然,如果要建立相同COM對象的多個執行個體,這不是非常有效,在這種情況下就要自大闖將一個類廠的執行個體,並在刪除它之前使用它的CreateInstance方法來建立COM對象。}

正如以前提到的,CreateComObject通常返回一個IunKnown指標。要擷取需要的介面針,應使用as操作符,如:

MyIntf := CreateCOmObject(CLSID_MyServer) as IMyInterface



執行個體:一個簡單的COM應用程式

在討論了COM伺服器的一些基本概念之後,我們用一個簡單的小執行個體來說明如何調用以DLL形式提供服務的COM伺服器,之後,我們會對此COM伺服器進行擴充,並且會再給一個COM伺服器的進階編程,但一切需要一步一步的來。

執行個體說明:

此執行個體是當正確登入到COM伺服器時,就可以實現一個簡單的演算法,此處沒有給出COM伺服器與資料庫伺服器之間的串連,所以登入不是一個動態從資料庫使用者資訊表裡進行判斷,而是在程式中指定了一個固定的使用者名稱,當然,在此處,可以串連一些文本資料庫來進行動態判斷。此處的演算法很簡單,就是傳統的小猴子吃桃子的問題,一個小猴子有一些桃子,每天吃一半,因為嘴饞,又多吃一個,這樣每天就是吃一半多一個,當到了第十天時,吃完之後僅僅有一個了(此處的吃完仍然是吃了一半多一個),而演算法就是要知道小猴子子本來要多少只桃子。

問題分析:因為需要用到COM伺服器的一些方法,所以可以暫時作如下的決定:

使用者的資訊判斷,即登入是否成功讓伺服器來為我們判斷,用戶端僅僅是作簡單的錯誤性檢查和資料的提交,正真的實現一個瘦用戶端;

{說明:此處所說的瘦用戶端希望讀者朋友們不要僅僅根據字面意思來看用戶端,並非是用戶端的代碼越少越好,用戶端所要作的工作都讓伺服器去做才是瘦。其實,不應該如此去理解,而我們一般理解的伺服器/用戶端應該是伺服器幫用戶端處理一些邏輯上的、業務上的分析,而一些判斷性的錯誤可以由用戶端去完成,雖然是用戶端,但它同樣有一些自身的檢查在裡邊,雖然是伺服器端,它仍有一些任務由用戶端去完成,再更多的情況,也許對讀者朋友來說,感覺可能讓客戶做的更好}

演算法實際上很簡單,可以利用迴圈,也可以利用遞迴,在此僅僅做簡單的分析。我們用迴圈來處理的話應該需要從後邊入手,第十天剛剛吃的還有一個桃子,那麼第十天,就應該是四個,第九天是十個,第八天是二十二個……,如此類推,我們可以很容易的得出一共有多少個桃子,可以進行如下的處理:

Var

Acount : Integer;

Asum : Integer;

Begin

Asum := 1;

For Acount := 10 DownTo 1 do

Asum := ( Asum + 1 ) * 2;

End;

理解起來很容易,到了第十天吃過之後還剩一個桃子,那麼,第



相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。