什麼是ATL(Active Template Library)
ATL,Active Template Library活動模板庫,是一種微軟程序庫,支持利用C++語言編寫ASP代碼以及其它ActiveX程序。經過活動模板庫,能夠創建COM組件,而後經過ASP頁面中的腳本對COM對象進行調用。這種COM組件能夠包含屬性頁、對話框等等控件。
ATL簡介
一. 什麼是ATL
自從1993年Microsoft首次公佈了COM技術之後,Windows平臺上的開發模式發生了巨大的變化,以COM爲基礎的一系列軟件組件化技術將Windows編程帶入了組件化時代。廣大的開發人員在爲COM帶來的軟件組件化趨勢歡欣鼓舞的同時,對於COM開發技術的難度和煩瑣的細節也感到極其的不便。COM編程一度被視爲一種遙不可及的技術,令送牀健?⑷嗽畢M芄揮幸恢址獎憧旖蕕腃OM開發工具,提升開發效率,更好地利用這項技術。
針對這種狀況,Microsoft公司在推出COM SDK之後,爲簡化COM編程,提升開發效率,採起了許多方案,特別是在MFC(Microsoft Foundation Class)中加入了對COM和OLE的支持。可是隨着Internet的發展,分佈式的組件技術要求COM組件可以在網絡上傳輸,而又儘可能節約寶貴的網絡帶寬資源。採用MFC開發的COM組件因爲種種限制不能很好地知足這種需求,所以Microsoft在1995年又推出了一種全新的COM開發工具ATL。
ATL是ActiveX Template Library 的縮寫,它是一套C++模板庫。使用ATL可以快速地開發出高效、簡潔的代碼(Effective and Slim code),同時對COM組件的開發提供最大限度的代碼自動生成以及可視化支持。爲了方便使用,從Microsoft Visual C++ 5.0版本開始,Microsoft把ATL集成到Visual C++開發環境中。1998年9月推出的Visual Studio 6.0 集成了ATL 3.0版本。目前,ATL已經成爲Microsoft標準開發工具中的一個重要成員,日益受到C++開發人員的重視。
ATL究竟給開發人員帶來了什麼樣的益處呢?這還要先從ATL產生之前的COM開發方式提及。
在ATL產生之前,開發COM組件的方法主要有兩種:一是使用COM SDK直接開發COM組件,另外一種方式是經過MFC提供的COM支持來實現。
直接使用COM SDK開發COM組件是最基本也是最靈活的方式。經過使用Microsoft提供的開發包,咱們能夠直接編寫COM程序。可是,這種開發方式的難度和工做量都很大,一方面,要求開發者對於COM的技術原理具備比較深刻的瞭解(雖然對技術自己的深入理解對使用任何一種工具都是很是有益的,但對於COM這樣一整套複雜的技術而言,在短期內徹底掌握是很難的),另外一方面,直接使用COM SDK要求開發人員本身去實現COM應用的每個細節,完成大量的重複性工做。這樣作的結果是,不只下降了工做效率,同時也使開發人員不得不把許多精力投入到與應用需求自己無關的技術細節中。雖然這種開發方式對於某些特殊的應用頗有必要,但這種編程方式並不符合組件化程序設計方法所倡導的可重用性,所以,直接採用COM SDK不是一種理想的開發方式。
使用MFC提供的COM支持開發COM應用能夠說在使用COM SDK基礎上提升了自動化程度,縮短了開發時間。MFC採用面向對象的方式將COM的基本功能封裝在若干MFC的C++類中,開發者經過繼承這些類獲得COM支持功能。爲了使派生類方便地得到COM對象的各類特性,MFC中有許多預約義宏,這些宏的功能主要是實現COM接口的定義和對象的註冊等一般在COM對象中要用到的功能。開發者可使用這些宏來定製COM對象的特性。
另外,在MFC中還提供對Automation 和 ActiveX Control的支持,對於這兩個方面,Visual C++也提供了相應的AppWizard和ClassWizard支持,這種可視化的工具更加方便了COM應用的開發。
MFC對COM和OLE 的支持確實比手工編寫COM程序有了很大的進步。可是MFC對COM的支持是不夠完善和完全的,例如對COM接口定義的IDL語言,MFC並無任何支持,此外對於近些年來COM和ActiveX技術的新發展MFC也沒有提供靈活的支持。這是由MFC設計的基本出發點決定的。MFC被設計成對Windows平臺編程開發的面向對象的封裝,天然要涉及Windows編程的方方面面,COM做爲Windows平臺編程開發的一個部分也獲得MFC的支持,可是MFC對COM的支持是以其全局目標爲出發點的,所以對COM 的支持必然要服從其全局目標。從這個方面而言,MFC對COM的支持不能很好的知足開發者的要求。
隨着Internet技術的發展,Microsoft將ActiveX技術做爲其網絡戰略的一個重要組成部分大力推廣,然而使用MFC開發的ActiveX Control,代碼冗餘量大(所謂的「肥代碼 Fat Code」),並且必需要依賴於MFC的運行時刻庫才能正確地運行。雖然MFC的運行時刻庫只有部分功能與COM有關,可是因爲MFC的繼承實現的本質,ActiveX Control必須揹負運行時刻庫這個沉重的包袱。若是採用靜態鏈接MFC運行時刻庫的方式,這將使ActiveX Control代碼過於龐大,在網絡上傳輸時將佔據寶貴的網絡帶寬資源;若是採用動態鏈接MFC運行時刻庫的方式,這將要求瀏覽器一方必須具有MFC的運行時刻庫支持。總之MFC對COM技術的支持在網絡應用的環境下也顯得很不靈活。程序員
解決上述COM開發方法中的問題正是ATL的基本目標。
首先ATL的基本目標就是使COM應用開發儘量地自動化,這個基本目標就決定了ATL只面向COM開發提供支持。目標的明確使ATL對COM技術的支持達到淋漓盡致的地步。對COM開發的任何一個環節和過程,ATL都提供支持,並將與COM開發相關的衆多工具集成到一個統一的編程環境中。對於COM/ActiveX的各類應用,ATL也都提供了完善的Wizard支持。全部這些都極大地方便了開發者的使用,使開發者可以把注意力集中在與應用自己相關的邏輯上。
其次,ATL因其採用了特定的基本實現技術,擺脫了大量冗餘代碼,使用ATL開發出來的COM應用的代碼簡練高效,即所謂的「Slim Code」。ATL在實現上儘量採用優化技術,甚至在其內部提供了全部C/C++開發的程序所必須具備的C啓動代碼的替代部分。同時ATL產生的代碼在運行時不須要依賴於相似MFC程序所須要的龐大的代碼模塊,包含在最終模塊中的功能是用戶認爲最基本和最必須的。這些措施使採用ATL開發的COM組件(包括ActiveX Control)能夠在網絡環境下實現應用的分佈式組件結構。
第三,ATL的各個版本對Microsoft的基於COM的各類新的組件技術如MTS、ASP等都有很好的支持,ATL對新技術的反應速度大大快於MFC。ATL已經成爲Microsoft支持COM應用開發的主要開發工具,所以COM技術方面的新進展在很短的時間內都會在ATL中獲得反映。這使開發者使用ATL進行COM編程能夠獲得直接使用COM SDK編程一樣的靈活性和強大的功能。
本文的目的就是但願在有限的篇幅中可以使讀者對ATL的使用和基本原理有一個初步的瞭解,爲廣大的COM開發人員更好地使用ATL開發起到拋磚引玉的做用。
二. ATL基本技術
雖然使用ATL開發COM 應用是一件很是簡單的事情,可是在ATL簡單易用的界面後面卻包含着複雜的技術。面對ATL生成的大量代碼,咱們即便不去深刻地瞭解這些代碼的含義也能夠開發出COM應用來,可是若是咱們要充分地挖掘ATL的潛力,開發出更靈活、強大的COM應用,則必須對ATL使用的基本技術有所瞭解。研究ATL的實質最好的教材就是由Visual C++提供的ATL源代碼。本文這一部分只是對ATL中用到的最基本的技術進行簡單的介紹。
簡單地說來,ATL中所使用的基本技術包括如下幾個方面:
COM技術
C++模板類技術(Template)
C++多繼承技術(Multi-Inheritance)
COM技術是理解ATL的基礎,使用ATL進行開發要對COM技術的基本概念有最低限度的瞭解。因爲COM是一項很是複雜龐大的技術體系,限於本文的篇幅,這裏再也不贅述。對於本文中提到的COM基本概念也不作過多的解釋,請讀者參閱有關的參考書籍。
做爲ATL最核心的實現技術的模板是對標準C++語言的擴展,可是在大多數的C++編程環境中,人們不多使用它,這是由於模板的功能雖然很強,可是它內部機制比較複雜,須要比較多的C++知識和經驗才能靈活地使用它。在MFC中的CObjectArray等功能類就是由模板來定義的。徹底經過模板來定義程序的總體類結構,ATL是迄今爲止作得最爲成功的。
所謂模板類簡單地說是對類的抽象。咱們知道C++語言用類定義了構造對象(這裏指C++對象而不是COM對象)的方式,對象是類的實例,而模板類定義的是類的構造方式,使用模板類定義實例化的結果產生的是不一樣的類。所以能夠說模板類是「類的類」。
在C++語言中模板類的定義格式以下:
注意:<和>是左右尖括號,可能沒法正常顯示。
template < class T>
class MyTemp
{
MyTemp<T>( ){ };
~MyTemp<T>( ) { };
int MyFunc( int a) ;
}
………….
Int MyTemp<T>::MyFunc( int a)
{
}
首先使用C++的關鍵字「template」來聲明一個模板類的定義。在關鍵字後面是用尖括號括起來的類型參數。正是根據這個類型參數,編譯器才能在編譯過程當中將模板類的具體定義轉化爲一個實際的類的定義,即生成一個新的類。接下來的定義方式與普通的類定義十分類似,只是在類的函數定義中都要帶有類型參數的說明。
下面的程序段說明了模板類的用法:
typedef MyTemp<MyClass> myclassfromtemp;
myclassfromtemp m;
int a = m.Myfunc(10);
一般在使用模板類時爲了方便起見,使用一個關鍵字「typedef」爲新定義出來的類取一個名字。在上面的程序段中假設「MyClass」是一個由用戶定義的類,經過將這個類的名字做爲類型參數傳遞給模板類,咱們能夠建立一個新的類,這個類的行爲將以模板類的定義爲基礎,例如它具備模板類定義的全部成員函數,同時這個類又是對模板類行爲的一種修改,這種修改是經過用戶提供的類型參數來實現的。賦予模板類以不一樣的類型參數,則獲得行爲框架類似但具體行爲不一樣的一組類的集合。有了新的類的定義之後,咱們能夠象使用普通類同樣來建立一個類的實例,即一個新的對象,而且調用這個對象的成員函數。
模板類是對標準C++語言的最新擴展,雖然它的功能很強大,可是要想使用好模板類須要至關多的關於語言和編程的經驗和知識,並且錯誤地使用模板類又會對程序的結構和運行效率帶來大的反作用,所以通常的編程環境和編程書籍對模板類的使用都採起謹慎的態度。而ATL的核心就是由幾十個模板類構成的,經過研究ATL的源代碼可使咱們對模板類的使用有比較深入全面的認識。編程
多繼承技術同模板同樣,是C++語言中極具爭議性的技術。使用多繼承技術可使程序的設計和實現更加靈活,可是,因爲多繼承的複雜性和自身概念上的一些問題,使多繼承在各類面向對象的語言環境中獲得的支持都很是有限。例如Small Talk根本就不容許多繼承,一樣MFC也不支持多繼承技術。
多繼承最大的問題是所謂的「鑽石結構」。例以下面的代碼:
class A
{
.....
};
class B : public A
{
.. .
};
class C : public A
{
.....
};
class D : public C,B
{
........
}
因爲類D同時從類C和B繼承,所以在下面的語句中就會發生歧義:
D* pD = new D;
(A*)pD->Func(...);
因爲類D經過類C和類B 分別繼承了類A,這裏的強制轉化就會發生歧義。
ATL使用了C++最新規範中加入的兩個運算符號 static_cast、dynamic_cast代替簡單的強制轉化,從而消除多繼承帶來的歧義。使用這兩個運算符號,咱們能夠在對象運行過程當中獲取對象的類型信息。上面的代碼能夠採用下面的方式修改:
D* pD = new D;
static_cast<A*>(static_cast<B*>(pD))->Func(...);
爲何模板類和多繼承技術會成爲ATL主要的工具呢?緣由在於,採用模板能夠在編譯過程當中快速的生成具備用戶定製功能的類,這對於COM這樣一個複雜的技術體系在實現效率上獲得了很大的提升。經過使用模板類,用戶能夠把精力集中在本身開發的類的基本邏輯上,在完成了本身的類的設計之後,經過繼承不一樣的類,生成不一樣的模板類,就能夠快速地實現COM的功能,同時又避免了採用單繼承結構形成的大量功能冗餘。
總之,正是因爲在設計實現過程當中採用了模板類和多繼承技術,才使ATL成爲一個小巧靈活的COM開發工具,可以適應開發人員對COM應用開發的各類須要。
三. ATL基本使用
這一部分將重點介紹ATL的基本使用過程。因爲ATL已經被集成在Microsoft Visulal Studio的Visual C++開發環境中,所以要使用ATL必須先安裝Visual C++。在下面的討論中有關COM的基本知識請參閱有關的文檔,這裏再也不詳細說明。給出的圖是在Microsoft Windows 98平臺下Visual Studio 6.0的使用示意圖。
使用ATL開發一個COM應用基本能夠分爲如下幾個步驟:
建立一個新的ATL工程,並對工程的選項進行適當的配置。
向新建立的工程添加新的ATL類,並對該類進行一些初始配置工做。
根據COM應用的基本要求向新的ATL類加入新的接口定義,並實現相應的接口成員函數。
編譯鏈接工程,註冊COM應用。
下面將根據這些步驟依次介紹ATL的基本使用過程。
1. 建立工程
首先啓動Visual C++集成開發環境,選擇「File」菜單下的「New...」命令,在「New」對話框中選擇「Project」頁。
選擇「ATL COM AppWizard」項,這是建立ATL工程的AppWizard嚮導入口。而後在「Project name」編輯框中輸入工程的名字,單擊「OK」按鈕,進入AppWizard對話框。
在AppWizard對話框中主要的設置選項有:
COM服務程序的類型:
- 動態鏈接庫(Dynamic Linking Library) 最終產生一個動態鏈接庫(DLL)形式的COM服務程序;
- 應用程序(Executable application)最終產生一個可執行程序類型(EXE)的COM服務程序;
- NT服務(NT Service):產生一個以NT服務方式運行的COM服務程序。
容許嵌入Proxy/Stub代碼。由Microsoft提供的MIDL編譯IDL文件之後,將產生用於對象調度(Marshaling)的Proxy/Stub的代碼。傳統地,這部分代碼與COM服務程序的代碼是分離的,可是因爲新的COM標準支持多線程環境下的COM對象服務,所以在動態鏈接庫的COM服務程序中也要有Proxy/Stub的支持。爲了支持在網絡上的傳輸,ATL容許用戶選擇將Proxy/Stub的代碼包括在生成的DLL代碼中。這個選項在EXE和NT服務類型的COM應用條件下不可選。
容許支持MFC。因爲ATL對除COM之外的基本的Windows編程方面的支持極爲有限,同時許多程序員對MFC又很是熟悉,所以在ATL的工程設置中容許在ATL工程內部支持使用MFC,便可以使用MFC定義的類。這在一方面來看是很是方便的,特別是對於習慣於使用MFC的開發人員來講,可以使用MFC提供的各類功能強大的類的支持,而沒必要直接使用Windows SDK。從另外一個方面來看,在ATL工程中使用MFC同時就喪失了ATL代碼輕量級的特色。
支持MTS。MTS是Microsoft Transaction Server的縮寫,它是Microsoft在COM技術方面的一個新的分支,這裏不做詳細說明。
完成上面的設置之後,能夠選擇FINISH完成工程的設置,ATL將建立相應的工程。
2. 加入ATL類
完成工程的建立和設置之後,下一步就是向工程中加入一個新的ATL類。Visual Studio集成環境提供了嚮導工具「ATL Object Wizard」用於加入一個新的ATL類。操做過程並不複雜,只是一組對話框操做而已。
首先經過集成環境的「Insert」菜單下的「New ATL Object…」命令進入「ATL Object Wizard」對話框。瀏覽器
這個對話框即爲建立ATL對象的嚮導起始界面。對話框的左邊部分說明了待建立對象的基本類型,這裏主要有如下的幾種類型:
對象(Object)基本的COM對象類型;
控制(Control)ActiveX Control類型的ATL對象;
其餘(Miscellaneous)輔助功能,如對話框的生成等;
數據訪問(Data Access)數據訪問,支持MTS等。
右邊部分說明了每種類型的詳細內容,對於通常的COM服務程序,使用對象表中的簡單對象(Simple Object)就能夠了。
選定待建立對象的基本類型之後,單擊「Next>」按鈕進入下一步,進入對象屬性設置對話框,如圖4和圖5所示。
對象屬性設置分爲兩個過程:先是對象名字標識的設定,而後是對對象的基本屬性進行設置。首先是對象的名字標識設置。
在對象標識編輯框中輸入待建立對象的名字,ATL對象嚮導將同步地根據用戶輸入的對象標識設定該對象的C++標識和COM標識。對象的C++標識包括對象的類名,cpp文件名和頭文件名。COM標識包括對象在類型庫中的CoClass段和實現的主接口的名字,同時還有在系統註冊表中的類型名以及ProgID。
對象名字標識設置完成之後,選擇對象屬性頁(Attribute)進入對象的屬性設置頁面。
對象的屬性設置是ATL對象建立過程當中最複雜的部分,包括如下幾個主要部分:
對象的線程模型(Thread Model)
對象的線程模型是COM對象在多線程環境下被訪問時對訪問方式的控制,缺省狀況下在ATL中採用的是套間模型Apartment,由系統經過消息隊列方式提供併發控制。
對象的接口模型(Interface)
COM對象的接口能夠是雙接口(Dual Interface)。雙接口不一樣於普通接口(Custom Interface) 之處在於雙接口是從Automation基本接口IDispatch繼承的,而普通接口是從IUnknown接口直接繼承來的。缺省的接口模型是雙接口。
對象的聚合模型(Aggregate)
COM規範不容許對象的實現繼承,可是能夠經過聚合方式重用其它的COM對象。ATL對象屬性設置中的聚合模型能夠指定待建立的COM對象是否支持聚合模型。缺省的選項是支持對象的聚合。
對象對錯誤處理的支持(Support ISupportErrorInfo)
選取這個選項能夠在對象的運行過程當中支持錯誤處理。缺省狀況下這個選項不被選中。
對象對鏈接點的支持(Support Connection Points)
鏈接點是COM對象的事件機制。選中這個選項可使待建立的COM對象具備發出事件的能力。缺省狀況下該選項不被選中。
對象對自由線程調度的支持(Free Thread Marshaller, 簡稱FTM)
對象的自由線程調度是對象在處於自由線程模型狀態下,爲了簡化對象的訪問過程而採用的一種優化策略。缺省狀況下該選項不被選中。
對於上述的任何一個選項的詳細描述都涉及到COM技術一些核心的內容,而且都已超出本文的範圍,所以本文只對ATL給出的缺省選項加以說明,對這些內容感興趣的讀者能夠參考Microsoft提供的文檔。
完成了上面的設置之後,就能夠按「OK」按鈕完成對象的建立過程。下一步就是向所生成的ATL類的接口中加入成員函數的定義,以及接口成員函數的實現過程。
3. 加入接口定義,實現接口函數
加入了ATL類定義以後,咱們能夠打開Visual C++集成環境下項目管理器(Workspace)中的Class View來檢查生成的類定義的狀況。咱們能夠看到一個新的類已經生成,同時,還生成了相應的接口定義。ATL Object Wizard爲咱們生成了類定義的.h 和.cpp文件,此外還有用於接口定義的IDL文件。有了這些文件之後,咱們就能夠爲接口加入成員函數,完成類的定義。
首先在Class View中選中相應的接口,顯示爲接口IATLTest,單擊鼠標右鍵打開菜單,如圖7。此彈出式菜單定義了爲接口加入屬性和方法的操做。選取其中的「Add Method...」項,能夠爲接口加入方法成員;選取「Add Property...」則能夠爲接口加入新的屬性成員。
加入屬性和方法的對話框能夠參看圖8和圖9。若是咱們要在接口中加入一個方法,則選取「Add Method...」菜單命令。假設方法名爲ABC,方法的返回類型爲COM規定的HRESULT類型。咱們也能夠定義非HRESULT返回類型的函數,可是這須要手工修改接口定義的IDL文件。咱們定義ABC方法的一個參數爲a,類型爲整數型。完成了方法的定義之後,單擊「OK」按鈕則把此方法加入到接口中。
屬性的加入過程是相似的。屬性加入對話框要求指定屬性的類型、名字以及屬性的訪問方式。在屬性和方法的編輯對話框中都有一個「Attributes」按鈕,在給出了一個屬性或方法的基本定義以後,單擊此按鈕,能夠對屬性和方法的一些高級特性進行設置。
方法成員加入之後,咱們能夠經過Class View來檢查ATL爲咱們所作的工做。首先咱們看到ATL在接口的定義中加入了該方法的定義;同時在對應的ATL類定義中,也加入了一個相應的方法的定義;在類對應的.cpp文件中,加入了此方法的實現框架。此後,咱們只要在這個函數框架中加入該方法的代碼邏輯,一個接口函數的定義和實現就基本完成了。依照這種方式,咱們能夠完成整個COM對象的定義和實現。
完成以上的步驟以後,咱們就能夠編譯鏈接應用了。
4. 編譯鏈接應用、註冊COM服務程序
對ATL工程的編譯鏈接過程包括下面的幾個步驟:
使用MIDL編譯工程的IDL文件,造成接口定義的頭文件和用於調度(Marshalling)的代碼;
編譯工程的.cpp文件造成目標文件;
鏈接目標文件,造成應用模塊;
註冊COM服務程序。
關於工程編譯鏈接的其它部分同Visual C++中MFC工程的編譯鏈接過程類似,這裏只重點介紹一下COM服務程序的註冊過程。服務器
在ATL中,COM服務程序的註冊是在工程編譯鏈接的最後階段,由ATL輔助完成的。在手工的COM編程中,服務程序的註冊是比較麻煩的工做。在ATL中,系統經過讀取在創建工程過程當中造成的註冊腳本文件來完成註冊工做。註冊腳本(Register Script 簡稱RGS)是ATL提供的文本方式的註冊輔助文件。下面是註冊腳本文件的一個實例。
HKCR - 表示註冊表中COM對象的註冊項,是HKEY_CLASS_ROOT的縮寫
{
AuthTest.ActiveXObject.1 = s 'ActiveXObject Class'
{
CLSID = s ''
} - 對象的ProgID
AuthTest.ActiveXObject = s 'ActiveXObject Class'
{
CLSID = s ''
} -對象的與版本無關的ProgID
NoRemove CLSID -對象CLSID註冊項
{
ForceRemove = s 'ActiveXObject Class'
{
ProgID = s 'AuthTest.ActiveXObject.1'
VersionIndependentProgID = s 'AuthTest.ActiveXObject'
InprocServer32 = s '%MODULE% -服務器類型,表示DLL服務器
{
val ThreadingModel = s 'both' -線程模型,這裏是BOTH型
}
}
}
}
RGS文件包含註冊COM服務程序的各項內容,通N頤遣槐匭薷拇薘GS文件,必要時咱們也能夠手工修改RGS文件來定製模塊的註冊過程。
四. 應用ATL的一個例子
上面介紹了使用ATL建立一個COM服務程序的基本過程。在介紹過程當中,咱們實際上已經生成了一個COM服務程序的基本框架,只是沒有填寫實際的內容。在下面部分,咱們實際開發一個十分簡單的COM服務程序,而且爲它編寫一段客戶代碼進行測試,使你們對使用ATL開發COM服務程序的過程有一個全面總體的瞭解。
咱們要開發的服務程序的功能很簡單,它只實現一個接口,這個接口名字是ISimpleInterface,接口只有一個成員函數,叫作Welcome。這個函數的功能只是輸出一個「Hello World!」的字符串。
按照上一部分介紹的建立COM服務程序的步驟,咱們進行以下的操做:
1 打開Visual C++集成開發環境;
2 建立一個稱爲SimpleTest的ATL工程;
3 在這個工程中插入新的對象,對象的名字是SimpleInterface;
4 設置接口ISimpleInterface的有關屬性,使它成爲一個雙接口;
5 在對象的接口ISimpleInterface中加入方法Welcome;
6 打開ATL加入的Welcome方法的框架,能夠看到以下的代碼段:網絡
STDMETHODIMP CActiveXObject::get_TestProp(long *pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
// TODO: Add your implementation code here
return S_OK;
}
7 將程序框架中的註釋部分替換爲下面的代碼:
::MessageBox(NULL,_T(」Hello World!」),_T(」Welcome」), MB_OK);
Welcome方法被調用時將彈出一個消息框。
8 編譯鏈接工程。
上面的步驟完成之後,咱們就有了一個簡單的COM服務程序,並且已經被註冊到當前系統中。
下面咱們要完成一個簡單的COM客戶程序。一個COM客戶程序簡單地說是使用COM組件對象的程序。客戶程序調用COM對象的基本流程是:
建立COM對象的實例。這能夠經過調用Windows系統的API函數CoCreateInstance來完成。
經過接口調用函數。
調用IUnknown::Release釋放COM對象實例
咱們的客戶程序是使用MFC編寫的一個基於對話框的簡單應用程序。具體的過程以下:
1 打開Visual C++集成開發環境;
建立一個稱爲SimpleClient的基於對話框的MFC工程;
在對話框中加入一個按鈕,名字爲TEST;
在SimpleClient.cpp文件中加入以下的代碼:
(1) 在cpp文件 #include 「simpleclientdlg.h」以後加入下面的代碼:
#include 「d:\simpletest\simpletest_i.h」 // 根據須要修改頭文件的路徑
加入的頭文件是在編譯COM服務程序過程當中自動生成的,其中包含接口自己的定義、接口IID的定義和COM對象的CLSID的定義。包含該頭文件可使客戶程序可以使用COM服務程序。
(2) 在按鈕TEST的消息控制函數中加入以下的代碼:
HRESULT hr;
ISimpleInterface* pIntf = NULL;
hr = CoCreateInstance(CLSID_SimpleInterface, NULL, CLSCTX_SERVER ,
IID_ISimpleInterface, (void **)& pIntf);
if(SUCCEEDED(hr))
{
pIntf->Welcome();
pIntf->Release();
}
上面的代碼首先經過系統API CoCreateInstance建立COM對象,獲得接口的指針,而後調用接口成員函數Welcome,最後經過IUnknown::Release()函數釋放COM對象實例。
編譯鏈接客戶程序
最後,咱們能夠測試客戶程序是否正常運行。啓動客戶程序,當單擊「TEST」按鈕時咱們能夠看到彈出一個消息框,這正是咱們的COM服務程序提供的功能。多線程
更多內容介紹:http://url7.me/bjcF1併發