本文將論述插件技術的基本原理,并給出三種不同的實現(xiàn)插件系統(tǒng)的方法。最重要的部分則是插件與主程序之間的交互插件,一般是一個遵循了某些特定規(guī)則的DLL,而主程序?qū)⑺胁寮涌谠趦?nèi)存中的地址傳遞給插件插件則根據(jù)這些地址來調(diào)用插件接口完成所需功能獲取所需資源等。
插件的木質(zhì)是在不修改程序主體的情況下對軟件功能進行加強。當插件的接口被公開時任何人都可以自己制作插件來解決一些 操作上的不便或增加一些功能。一個插件框架包括兩個部分:主程序(host)和插件((plug-in)。主程序即是“包含”插件的程序。插件必須實現(xiàn)若干標準接口,由主程序在與插件通信時調(diào)用。
編程實現(xiàn)方面包括兩個部分:一部分是主體程序的插件處理機制,用來進行初始化每個插件的過程,并且管理好每個插件接口。另一部分是插件的接口函數(shù)定義,將所有的插件接口函數(shù)進行封裝。以便開發(fā)者自由調(diào)用。
不管用什么手段實現(xiàn)插件和主程序之間的交互必須有一個協(xié)議,對于方法(1)這個協(xié)議是一系列的函數(shù)。這些函數(shù)由插件DLL引出由主程序調(diào)用。對于方法〔2)協(xié)議則是一個(或多個)基類通常是抽象類,插件需要構造一個類來繼承此抽象類并實現(xiàn)其接口方法,再為主程序提供一個創(chuàng)建和銷毀此實現(xiàn)類的對象的公共方法這個公共方法理所當然也應成為協(xié)議的一部分。對于方法(3)則是一個(或多個)COM接口插件是一個COM組件,它實現(xiàn)了這些接口,并注冊到約定的組件類別tcomponent category)下。
一般音頻播放器都有這樣一些基本功能:裝載音頻文件(LoadFlle)、播放(Play)、暫停(Pause),停止((Stop)。我們的播放器將提供這四個功能,但主程序本身并不會直接實現(xiàn)這些功能而是調(diào)用插件的實現(xiàn),上文已經(jīng)說過。每個插件支持一種音頻格式,所以每個插件的功能實現(xiàn)都是不同的。在主程序打開某個格式的音頻文件時,根據(jù)文件擴展名來決定調(diào)用哪個插件的功能,主程序可以在啟動時加載所有插件,也可以在打開文件時動態(tài)加載所需插件,甚至可以在啟動時加載一部分常用的插件,而在需要時加載其余插件開發(fā)者可以有很高的自由度
主程序是一個基于對話框的標準Windows程序,它啟動時會搜索約定目錄(可以約定所有插件都存放在主程序所在目錄的Plugins子目錄下),并使用Wia32函數(shù)LoadLrbrary加載所有插件,每加載一個插件DLL,就調(diào)用另一個Wun32函數(shù)GetProcAddress獲取引出函數(shù)
GetSupportedformat的地址,并調(diào)用此函數(shù)返回插件所支持的格式名(即是音頻文件的擴展名),然后把(格式名,DLL句柄)二元組保存下來,當用戶通過菜單打開文件時,主程序會根據(jù)擴展名決定調(diào)用哪個插件的LoadFile函數(shù),并指明此插件DLL的句柄為當前使用的插件的DLL句柄(比如保存到變量m_hlnst中),此后當用戶