于珊珊
摘要:討論了插件技術(shù)的原理、插件的管理、插件的實(shí)現(xiàn)方案,在此基礎(chǔ)上研究了插件技術(shù)在數(shù)據(jù)庫(kù)開(kāi)發(fā)過(guò)程中的應(yīng)用。
關(guān)鍵詞:插件接口數(shù)據(jù)庫(kù)系統(tǒng)開(kāi)發(fā)
1插件技術(shù)的原理
1.1動(dòng)態(tài)鏈接庫(kù)(Dynamic Link Li-brary)
它本身不能獨(dú)立運(yùn)行,但它能輸出函數(shù)或類(lèi),通過(guò)其它能獨(dú)立運(yùn)行的程序(宿主程序)可以調(diào)用它內(nèi)部的功能。動(dòng)態(tài)鏈接庫(kù)有兩種調(diào)用方式:
(1)靜態(tài)調(diào)用方式:由編譯系統(tǒng)完成對(duì)DLL的加載和應(yīng)用程序結(jié)束時(shí)DLL卸載的編碼。
隱式的調(diào)用:需要把產(chǎn)生動(dòng)態(tài)連接庫(kù)時(shí)產(chǎn)生的,LIB文件加入到應(yīng)用程序的工程中,想使用DLL中的函數(shù)時(shí),只須說(shuō)明一下。隱式調(diào)用不需要調(diào)用LoadLibrary()和FreeIAbrary()。程序員在建立一個(gè)DLL文件時(shí),鏈接程序會(huì)自動(dòng)生成一個(gè)與之對(duì)應(yīng)的LIB導(dǎo)入文件。該文件包含每一個(gè)DLL導(dǎo)出函數(shù)的符號(hào)名和可選的標(biāo)識(shí)號(hào),但是并不含有實(shí)際的代碼。LIB文件作為DLL的替代文件被編譯到應(yīng)用程序項(xiàng)目中。當(dāng)程序員通過(guò)靜態(tài)鏈接方式編譯生成應(yīng)用程序時(shí),應(yīng)用程序中的調(diào)用函數(shù)與LIB文件中導(dǎo)出符號(hào)相匹配,這些符號(hào)或標(biāo)識(shí)號(hào)進(jìn)入到生成的EXE文件中。LIB文件中也包含了對(duì)應(yīng)的DLL文件名(但不是完全的路徑名),鏈接程序?qū)⑵浯鎯?chǔ)在EXE文件內(nèi)部。
當(dāng)應(yīng)用程序運(yùn)行過(guò)程中需要加載DLL文件時(shí),Windows根據(jù)這些信息發(fā)現(xiàn)并加載DLL,然后通過(guò)符號(hào)名或標(biāo)識(shí)號(hào)實(shí)現(xiàn)對(duì)DLL函數(shù)的動(dòng)態(tài)鏈接。所有被應(yīng)用程序調(diào)用的DLL文件都會(huì)在應(yīng)用程序EXE文件加載時(shí)被加載到內(nèi)存中??蓤?zhí)行程序鏈接到一個(gè)包含DLL輸出函數(shù)信息的輸入庫(kù)文件(.LIB文件)。操作系統(tǒng)在加載使用可執(zhí)行程序時(shí)加載DLL??蓤?zhí)行程序直接通過(guò)函數(shù)名調(diào)用DLL的輸出函數(shù),調(diào)用方法和程序內(nèi)部其他函數(shù)一樣。
(2)動(dòng)態(tài)調(diào)用方式:由編程者用API函數(shù)加載和卸載DLL調(diào)用DLL,使用較復(fù)雜,但能更有效地使用內(nèi)存,是編制大型應(yīng)用程序的重要方式。
顯式的調(diào)用:是指在應(yīng)用程序中用I.oadLibrary或MFC提供的AfxLoadLibrary顯式的將自己所做的動(dòng)態(tài)連接庫(kù)調(diào)進(jìn)來(lái),動(dòng)態(tài)連接庫(kù)的文件名即是上面兩個(gè)函數(shù)的參數(shù),再用GetProcAddress()獲取想要引入的函數(shù)。自此,你就可以象使用如同本應(yīng)用程序自定義的函數(shù)一樣來(lái)調(diào)用此引入函數(shù)了。在應(yīng)用程序退出之前,應(yīng)該用FreeLibrary或MFC提供的MxFreeLi-brary釋放動(dòng)態(tài)連接庫(kù)。直接調(diào)用Win32的LoadLibary函數(shù),并指定DLL的路徑作為參數(shù)。LoadLibary返回HINSTANCE參數(shù),應(yīng)用程序調(diào)用GetProcAddress函數(shù)時(shí)使用這一參數(shù)。C,etProcAddress函數(shù)將符號(hào)名或標(biāo)識(shí)號(hào)轉(zhuǎn)換為DLL內(nèi)部的地址。程序員可決定DLL文件何時(shí)加載或不加載,顯式鏈接在運(yùn)行時(shí)決定加載哪個(gè)DLL文件。使用DLL的程序在使用之前必加載(LoadLibrary)DLL,得到一個(gè)DLL模塊的句柄,然后調(diào)用GetPro-cAddress函數(shù)得到輸出函數(shù)指針,在退出之前必卸載(FreeLibrary)DLL。
1.2接口。宿主程序與插件只能通過(guò)制訂好的接口進(jìn)行通信。軟件開(kāi)發(fā)中,接口只是定義功能并規(guī)定調(diào)用功能的形式,而不包含功能的實(shí)現(xiàn)。接口實(shí)質(zhì)上是軟件模塊的調(diào)用規(guī)范。就開(kāi)發(fā)支持插件功能的應(yīng)用程序而言,一般來(lái)說(shuō)由宿主程序的開(kāi)發(fā)者來(lái)制訂接口,如果希望其他的開(kāi)發(fā)人員能開(kāi)發(fā)相關(guān)的插件,只要公開(kāi)相關(guān)的接口即可。接口功能一般由插件方實(shí)現(xiàn)。因?yàn)椴寮膶?shí)現(xiàn)也許要調(diào)用宿主程序的功能,所以接口功能也可能由宿主程序來(lái)實(shí)現(xiàn)。也就是說(shuō),宿主程序與插件的信息流可能是雙向的。接口的調(diào)用規(guī)范與功能實(shí)現(xiàn)相互分離有一個(gè)很大的優(yōu)點(diǎn):盡管不同的插件開(kāi)發(fā)者對(duì)同一個(gè)接口的具體實(shí)現(xiàn)不同,但是在宿主程序中對(duì)這些插件的調(diào)用方式是一樣的。如果有宿主程序?qū)崿F(xiàn)的接口,在不同的插件中也可以用相同的使用方式調(diào)用宿主程序的功能。這極大地提高了應(yīng)用程序的靈活性。
1.3開(kāi)發(fā)支持插件功能應(yīng)用程序的解決方案。(在動(dòng)態(tài)鏈接庫(kù)中實(shí)現(xiàn)插件接口,在宿主程序中運(yùn)用顯式鏈接方式動(dòng)態(tài)加載插件。支持插件功能的應(yīng)用程序的結(jié)構(gòu)如圖1所示。在宿主程序中,插件管理部分用于管理插件的安裝和刪除,并將所安裝插件的信息保存到適合的地方,例如保存到注冊(cè)表或配置文件中。宿主程序啟動(dòng)時(shí),根據(jù)插件的配置信息加載插件模塊,然后獲得插件的輸出函數(shù)或輸出類(lèi)的指針并加以保存,如果需要的話(huà),可以向宿主程序增加界面接口元素,如菜單、工具條按鈕等。在宿主程序中當(dāng)點(diǎn)擊與插件相關(guān)聯(lián)的接口元素(如菜單等)時(shí),就會(huì)觸發(fā)插件調(diào)用函數(shù),在插件調(diào)用函數(shù)中使用宿主程序中所保存的插件信息調(diào)用插件中實(shí)現(xiàn)的功能。在調(diào)用插件輸出函數(shù)時(shí)也可以把宿主程序中實(shí)現(xiàn)的接口傳遞給插件方。
2插件管理
主程序必須為支持插件提供插件管理功能,它調(diào)用了插件提供的接口,其具體實(shí)現(xiàn)實(shí)際上是由插件本身完成的。插件管理主要提供以下幾個(gè)方面的功能:(1)注冊(cè)、反注冊(cè)插件。(2)啟用、禁用插件。(3)顯示插件基本信息。(4)配置插件參數(shù)。
3插件的實(shí)現(xiàn)方案
對(duì)于插件的實(shí)現(xiàn),有動(dòng)態(tài)鏈接庫(kù)(DLL)、COM組件兩種方案,目前的系統(tǒng)中,采用動(dòng)態(tài)鏈接庫(kù)(DLL)方案。(1)DLL是在Windows系統(tǒng)中實(shí)現(xiàn)軟件組件重要的方法,在動(dòng)態(tài)鏈接庫(kù)(DLL)中,集中實(shí)現(xiàn)插件,只需用戶(hù)有在Windows下編寫(xiě)一般DLL的經(jīng)歷,再花少量的時(shí)間熟練有關(guān)插件的調(diào)用規(guī)則及編程規(guī)則,就可進(jìn)行插件設(shè)計(jì)與開(kāi)發(fā);(2)COM,即組件對(duì)象模型,是一種以組件為發(fā)布單元的對(duì)象模型,這種模型使各軟件組件可以用一種統(tǒng)一的方式進(jìn)行交互。COM既提供了組件之間進(jìn)行交互的規(guī)范,也提供了實(shí)現(xiàn)交互的環(huán)境,由于同類(lèi)插件一般有統(tǒng)一的調(diào)用接口,因此也可使用COM技術(shù)作為開(kāi)發(fā)插件的基礎(chǔ)。COM接口是COM對(duì)象與系統(tǒng)之間的交互通道,而調(diào)用插件的函數(shù)在同類(lèi)插件間是基本相同的,因而,可把插件的初始化及調(diào)用插件的交互通道定義為插件的接口,則編寫(xiě)插件也就是編寫(xiě)COM插件的過(guò)程,同時(shí),也有利于多個(gè)插件實(shí)現(xiàn)在一個(gè)COM組件中,并應(yīng)用組件的聚合等專(zhuān)有技術(shù)實(shí)現(xiàn)功能更強(qiáng)的插件。使用COM技術(shù)作為編寫(xiě)插件的技術(shù),更易于在插件與系統(tǒng)間進(jìn)行交互操作,對(duì)編寫(xiě)插件及擴(kuò)大插件的使用范圍是很有利的;但與之相應(yīng)的是,應(yīng)用COM技術(shù)編寫(xiě)插件時(shí),涉及大量的COM技術(shù)及原理,導(dǎo)致開(kāi)發(fā)者難以迅速地應(yīng)用該項(xiàng)技術(shù)編寫(xiě)插件來(lái)解決實(shí)際問(wèn)題。
4插件技術(shù)在數(shù)據(jù)庫(kù)開(kāi)發(fā)中的應(yīng)用
由于系統(tǒng)設(shè)計(jì)上已經(jīng)使用插件技術(shù),將每項(xiàng)功能都單獨(dú)設(shè)計(jì),使得系統(tǒng)在開(kāi)發(fā)過(guò)程中變得更加可視,可控,易控,用插件技術(shù)設(shè)計(jì)數(shù)據(jù)庫(kù)系統(tǒng)并不是簡(jiǎn)單的將數(shù)據(jù)庫(kù)系統(tǒng)劃分模塊,它已經(jīng)將每項(xiàng)功能都劃分成了單獨(dú)設(shè)計(jì)體,因此,在每項(xiàng)功能的開(kāi)發(fā)過(guò)程中,都可以明確每一項(xiàng)功能的開(kāi)發(fā)責(zé)任,可以明確每一項(xiàng)功能的結(jié)構(gòu),輸入,輸出,所需數(shù)據(jù),處理方式等要素。它將模塊更加細(xì)化,并切斷了模塊當(dāng)中每一項(xiàng)功能之間的聯(lián)系,減少了制約因素。這就使開(kāi)發(fā)進(jìn)度表由模塊級(jí)劃分變成由功能級(jí)劃分,由模塊進(jìn)度線(xiàn)變成功能進(jìn)度線(xiàn),從而擴(kuò)大了單位時(shí)間的開(kāi)發(fā)量,變縱向式開(kāi)發(fā)為橫向式開(kāi)發(fā)。在功能開(kāi)發(fā)完畢。進(jìn)行調(diào)試過(guò)程當(dāng)中,由于開(kāi)發(fā)使用了插件技術(shù),使得調(diào)試工作更加簡(jiǎn)單,調(diào)試內(nèi)容變得更少,更有利于進(jìn)行白盒測(cè)試,保證了軟件的質(zhì)量。