1、自動化技術
自動化技術既以前提到的OLE自動化。雖然自動化技術建立在COM基礎上,但自動化要比COM應用廣泛得多。一方面,自動化繼承了COM的很多優點,比如語言無關、進程透明等特性;另一方面,自動化簡化了COM的一些底層細節,比如屬性和方法的處理、一組專用於自動化的數據類型等。自動化也是OLE的基礎,所以可以把自動化看作COM和OLE中間的一項技術。自動化的核心是IDispatch接口,每一個自動化對象都必須實現IDispatch接口。自動化技術並不復雜,它實際上是COM的一個特例。
2、自動化產生與發展
COM的語言無關性在使用一些弱類型的高級語言時很受限制,而自動化為這些高級語言提供了另一條程序相互通信的直觀且友好的途徑。
自動化技術的發展與Visual Basic和VBA有直接的關系。首先,VBA(或VBScript)已經發展成為大多數Microsoft應用程序擴展的標准,其次,Microsoft Visual Basic開發工具的成功應用也推動了自動化對象的發展。自動化技術為Visual Basic與其他語言的協作開發提供了一條捷徑。
通過自動化編程接口,不同應用程序之間的通信可以在VBA或者VBScript層次上進行,甚至根本不需要知道列集和RPC調用的概念。自動化是位於上層(應用層)的組件技術,它可以面對最終用戶,比如宏語言編程。
自動化對象的IDispatch接口可以作為OLE的標准接口,由於OLE已經提供了標准的接口代理和存根組件,所以自動化對象即可以運行在DLL組件中,也可以運行在EXE組件中。如果在分布式環境下,那麼自動化對象可以被遠程客戶創建或連接。
3、屬性和方法
方法(method)和屬性(property)是自動化對象的兩個基本特性,方法是指自動化對象所提供的功能服務;而屬性是指自動化對象的數據特征。
從本質上講,屬性是一個值,它既可以被設置,也可以被獲取。
方法要比屬性靈活得多,它們可以具有零個或多個參數,它們既可以設置也可以獲取對象數據,最常見的是完成某些動作。
自動化對象的屬性和方法都有符號化的名字,客戶程序通過名字就可以訪問到自動化對象的屬性或者方法。
4、類型庫和ODL
組件對象的類型信息是指它與外界進行交互的一些必要信息,包括組件的CLSID、它所支持接口的IID、接口的每個成員函數、成員函數的參數和返回值類型等等,類型信息中的數據類型也可以是自定義的數據類型,如C語言風格的結構、聯合、枚舉等。
Microsoft擴充了IDL形成ODL(object description language ,對象描述語言),可以描述組件對象的類型信息。一般來說,一個組件對象的類型信息包括每個接口的類型信息和對象的類型信息,接口類型信息的描述方法與 IDL完全兼容。接口類型信息使用interface 或dispinterface 關鍵字描述;對象類型信息使用coclass關鍵字進行描述。每個ODL文件可以描述多個組件對象,經過MIDL或者MkTypLib工具可編譯得到類型庫。通常把一個組件程序中的所有對象放在一個ODL文件中,並用library關鍵字描述庫信息,包括類型庫的ID(即LIBID)、類型庫所使用的語言、版本等。在ODL文件中也可以使用importlib引入其他類型信息。
用MIDL實用工具編譯ODL文件可以得到類型庫文件,其後綴為TLB,也可以產生相應的.h頭文件。
使用類型庫的好處有兩點。一是VB或者VBA可以使用類型庫來浏覽組件對象的方法和屬性,它也可以利用類型庫增強對屬性和方法的訪問;二是在實現自動化對象的IDispatch接口時,可以利用類型庫向客戶程序提供類型信息,這可使我們避免繁瑣的類型處理。
5、IDispatch接口
成員函數Invoke是個關鍵函數,客戶程序必須通過Invoke函數才能訪問屬性或方法,也可以說Invoke函數是自動化對象的命令翻譯器。
6、自動化兼容的數據類型
自動化對象使用的基本數據類型為VCRIANT結構類型。整個VARIANT結構的大小為16字節,但它描述了所有自動化對象可以使用的數據類型。
7、IDispatchEx接口
IDispatch接口描述的類型信息是靜態的,在運行過程中類型信息不會被改變,在編譯時刻通過類型庫就可以獲得所有的類型信息。然而,在一些腳本語言中,我們需要在運行時刻動態提供類型信息,IDispatchEx接口這是適應這樣的要求而建立起來的,它繼承了IDispatch接口的成員函數。
8、自動化對象實現——類型庫支持
9、自動化對象實現——Invoke函數實現
10、自動化對象實現——異常處理
11、自動化對象實現——多語種,本地化
12、自動化對象實現——用CreateStdDispatch函數實現自動化對象
13、自動化對象應用——雙接口
自動化控制器通過IDispatch接口可以調用自動化對象的所有方法和屬性,但由於這種調用是通過Invoke成員函數間接進行的,中間經過幾重處理,調用的效率損失很大。當然這種方式為高級語言客戶程序提供了極大的便利,不過有的客戶程序不一定希望這種效率損失,它希望能夠直接通過vtable調用到成員函數代碼。為了同時滿足這兩種情形,自動化對象可以在實現IDispatch接口的基礎上,把方法和屬性函數也以接口成員函數的方法暴露出去,這樣就形成了雙接口(dual interface)的概念
14、自動化對象應用——遲綁定和早綁定
由於自動化對象使用類型庫對參數類型進行檢查,而類型庫文件獨立於自動化組件,因此,不僅自動化對象可以利用類型庫實現它的IDispatch成員函數,自動化控制器也可以利用類型庫對方法或屬性的參數進行檢查。
如果自動化控制器利用對象的類型庫,在編譯時刻對參數類型和返回值類型進行檢查,並直接用分發ID調用Invoke函數,我們把這種調用方法稱為早綁定(early binding)技術。
相對應地,控制器也可以在運行時刻通過IDispatch接口的成員函數獲得類型信息,當它訪問一個屬性或方法時,它要調用IDispatch::GetIDsOfNames,以便根據符號化名字找到分發ID,我們把這種調用稱為遲綁定(late binding)技術。
選擇使用早綁定或者遲綁定取決於控制器的運行環境,而調用效率並不成為判斷的依據。
15、自動化對象應用——自動化集合對象
集合對象也是一個自動化對象,但它有一些特殊的要求。首先,作為一組同類對象(或數值)的容器對象,它必須提供枚舉這些成員的方法;其次,它必須支持Add、Remove和Item方法以及Count屬性。
16、自動化對象應用——一IDispatch作為出接口
17、自動化對象應用——自動化控制器
18、自動化對象編程——MFC對自動化對象的支持
19、自動化對象編程——COleDispatchDriver類
20、自動化對象編程——在Visual Basic中使用自動化對象