二次開發介面(API)與外掛程式(Addin)
許式偉 (著作權聲明)
2007-4-20
在前文,我們已經解釋了:
- 自動化(Automation)基礎概念:COM組件(Component)與介面(Interface)
- 自動化(Automation)基礎概念:變體(Variant)與Dispatch調用(IDispatch)
而同時,我們經常也可能經常聽到以下這些詞語:
- 自動化(Automation,COM Automation)
- OA(辦公自動化,Office Automation)
- 二次開發介面(應用程式開發介面,Application Programming Interface,API)
- 外掛程式(Addin,Addon)
等等。本文試圖解釋這些概念。
自動化(Automation)顧名思義是指“讓機器在沒有人工幹預的情況下自動完成特定的任務”。為了完成這一目標,自動化(Automation)技術的核心想法是,應用程式(Application)需要把自己的核心功能以DOM模型的形式對外提供,使得別人能夠通過這個DOM模型來使用該應用程式的功能。這也就是我們通常說的API——Application Programming Interface,簡稱API。為了與Windows API這樣的編程介面區分開來,我們引入一個專有名詞,叫“二次開發介面”。“二次開發”取意於“在現有應用程式基底礎上進行再開發”。其實如果你願意把作業系統當作一個更大的應用程式的話,二次開發介面和Windows API並沒有什麼很大的本質上的差異(儘管我們知道Windows API並不是以COM組件方式提供的)。
理解了自動化(Automation),OA(辦公自動化,Office Automation)就比較好解釋,無非是應用程式特指辦公軟體而已。而OA是指辦公(包括公文流轉)系統的自動化。
在應用程式提供了編程介面(API)的前提下,典型情況下,我們有兩種辦法來使用這些API。方法一是把應用程式當作一個Server,通過API對外提供服務。在此情形下,應用程式只是作為一個EXE COM Server的服務程式而已。只要我們理解進程間的LPC或者RPC調用是怎麼回事,那麼一切就非常Easy。方法二是實現一個應用程式外掛程式(Addin)。這種方法更有意思一些。首先,這是一種進程內的調用,效率非常好。其次,這是一種雙向的通訊,應用程式通過它提供的外掛程式機制感知到外掛程式的存在,並且將外掛程式載入上來;外掛程式則是在獲得活動權後,通過應用程式的API完成特定的功能。最後,也是最重要的,外掛程式與應用程式融為一體,實際上是擴充了應用程式的能力,使得應用程式變得更為強大。
外掛程式(Addins)的啟動過程大體如下:
- 應用程式啟動。通過註冊表(或者存放於其他任何地方)獲得外掛程式列表。外掛程式一般以 COM 組件形式提供,故此只要有一個外掛程式的 CLSID 或者 ProgID 的列表就可以了。另外,外掛程式的功能可以千差萬別,但是他們需要統一實現一個介面,例如 _IDTExtensibility2 或者類似的東西。這個介面在下面的第二步就用到了。
- 遍曆外掛程式列表,建立並初始化各外掛程式。關鍵是初始化。當然應用程式並不知道外掛程式想做什麼,它只是取得 _IDTExtensibility2(或者類似介面),調用其中的初始化函數(如 OnConnection)。
- 外掛程式獲得了初始化機會。注意,在初始化的時候,應用程式把自己的DOM模型的根介面(我們通常稱為Application)傳入。在 _IDTExtensibility2 中,根介面被定義為 IDispatch 類型,即 IDispatch* Application。但是實際上可以更通用,如IUnknown* Application。有了這個 Application 指標,外掛程式就可以為所欲為,做它想做的事情,調用它想要調用的任何API。
從外掛程式(Addins)展開來講,可以講非常多的內容。然而這不是本文的意圖。所以關於這方面的內容,我們只能留待以後有機會繼續這個話題。不過我還是忍不住把話題起個開頭:由於外掛程式(Addin)機制使得應用程式結構顯得更為靈活,所以,越來越多的軟體架構,追求一種超輕量的核心(也就是我們說的應用程式,之所以稱為核心,是因為它是組織一切的核心),並把更多的功能通過外掛程式(Addin)方式提供。超輕量的核心意味著需要解決一個額外的關鍵點:就是外掛程式(Addin)不只是擴充應用程式的功能,也同時擴充了應用程式的API,這些API與原有核心的API無縫地結合在一起,從而使得整個系統可以滾雪球一樣越滾越大。