??? 摘 要: 提出一種基于CAR構(gòu)件的用戶自定義事件" title="用戶自定義事件">用戶自定義事件機制。該機制是一種適用于嵌入式系統(tǒng)的,、用戶自定義的,、實現(xiàn)客戶與構(gòu)件間交互通信的計算機運行環(huán)境的事件管理機制及裝置。該機制可自動生成構(gòu)件,,生成構(gòu)件具有升級獨立性,、構(gòu)件互操作的簡單快速性,、接口重用性、構(gòu)件本地/遠程透明化,、編程語言無關(guān)性等特性,。該機制屏蔽了客戶程序調(diào)用構(gòu)件對象過程中繁瑣的細節(jié),大大簡化了客戶程序的實現(xiàn),。
?? ?關(guān)鍵詞: CAR構(gòu)件? 用戶自定義事件? 回調(diào)
?
??? 現(xiàn)有的構(gòu)件技術(shù)中客戶與構(gòu)件之間的通信過程多為單向,;客戶創(chuàng)建構(gòu)件對象,然后客戶調(diào)用對象所提供的接口函數(shù),,在這樣的交互過程中,,客戶總是主動的,而構(gòu)件對象則處于被動狀態(tài),。對于一個全面的交互過程,,這樣的單向通信往往不能滿足實際需要。
??? 微軟提供的可連接對象技術(shù)可實現(xiàn)構(gòu)件對客戶的調(diào)用,。但該技術(shù)需要用戶去實現(xiàn)客戶程序與構(gòu)件對象的連接,、事件的激發(fā)、接收器的編寫等,;而且只能以接口為單位注冊,,即不能為接口中每個成員函數(shù)分別注冊。另外,,Windows應(yīng)用程序" title="應(yīng)用程序">應(yīng)用程序都必須有一個消息循環(huán)以處理消息隊列中Windows發(fā)送過來的消息,。這樣每個應(yīng)用程序都有一個等待消息的線程,當同時運行的程序較多時,,占用系統(tǒng)資源比較大,。
??? COM技術(shù)主要解決的問題:不同來源的構(gòu)件實現(xiàn)互操作,構(gòu)件升級不影響其他構(gòu)件,、獨立于編程語言,,構(gòu)件在進程內(nèi)、跨進程甚至跨網(wǎng)絡(luò)運行的透明度,。但調(diào)用COM構(gòu)件對象的過程相當繁瑣,,不易操作。
??? 本文提出一種基于CAR構(gòu)件的用戶自定義事件機制,, 該機制能夠?qū)崿F(xiàn)構(gòu)件端和客戶端" title="客戶端">客戶端的交互操作,,跨平臺的構(gòu)件開發(fā)、運行環(huán)境和構(gòu)件庫,;其通過在操作系統(tǒng)上自動生成中間件(代理構(gòu)件),,提供構(gòu)件定位、調(diào)用,、管理,、中間件啟動生成,、構(gòu)件通信的進程內(nèi)、跨進程,、跨網(wǎng)功能,;并保證軟件互操作性、版本升級獨立性,,具有運行環(huán)境透明性,、軟件協(xié)同開發(fā)、軟件容錯,、可靠性、軟件復用,、軟件升級的能力,;具有構(gòu)件升級的獨立性、簡單快速的構(gòu)件互操作,、接口重用,、本地/遠程透明性、編程語言無關(guān)性的特性,。該機制還可自動實現(xiàn)標準接口類封裝層,,屏蔽調(diào)用COM構(gòu)件對象過程的繁瑣細節(jié),從而簡化客戶程序的實現(xiàn),。
??? 基于CAR構(gòu)件的用戶自定義事件機制,,其技術(shù)實現(xiàn)包括設(shè)置事件管理方(EventManager)、事件發(fā)送方(EventDispatcher)兩個方面,,兩者通過接口建立關(guān)聯(lián),,其具體實施過程如圖1所示。該機制包括事件管理方——客戶端以及事件發(fā)送方——構(gòu)件端,。其中連接點對象記錄了包含已注冊事件處理函數(shù)指針" title="函數(shù)指針">函數(shù)指針的接收器的接口指針,。其實施過程包括:(1)注冊事件時保存IDispatch接口指針到連接點對象中;(2)注冊事件時把標識該連接的dwCookie保存到EventHandler中,;(3)激發(fā)事件時,,利用所保存的IDispatch接口指針調(diào)用其Invoke方法;(4)利用EventHandler所保存的dwCookie注銷事件,。
?
?
??? 事件發(fā)送方組織不同參數(shù)構(gòu)成可連接對象事件,,可連接對象事件具有接口,用戶自定義事件函數(shù)接口注冊,。具體地,,事件發(fā)送方在可連接對象事件內(nèi)設(shè)置事件標識,事件管理方創(chuàng)建接收器,,將事件函數(shù)指針打包設(shè)置在事件管理方的接收器內(nèi),。接收器具有接口,,通過注冊與可連接對象端連接,把可連接對象接口指針寫入對應(yīng)的接收器內(nèi),,并把包含事件處理函數(shù)指針的接收器所提供的接口指針設(shè)置在對應(yīng)的可連接對象內(nèi),。在條件符合時,事件發(fā)送方激發(fā)事件,,通過接收器接口,,事件管理方回調(diào)" title="回調(diào)">回調(diào)函數(shù),并解包,,執(zhí)行程序,。事件管理方的接收器通過接口尋找事件標識,獲得該事件連接點對象的連接接口指針,。其中事件處理函數(shù)參數(shù)中的第一個參數(shù)包括該事件接口的類的智能指針,,用于標識事件的發(fā)送者;第二個及其后的參數(shù)與構(gòu)件定義中的事件參數(shù)定義相同,。接口包括普通接口和事件接口,。其中普通接口為入接口,用于向客戶端提供服務(wù),;事件接口為出接口,,用于事件發(fā)生時回調(diào)客戶端所注冊的事件處理函數(shù)。對象通過事件接口與客戶進行通信,,而每一個接口有惟一的標識符,,構(gòu)件若需添加新的功能,必須先定義新的接口描述,。當激發(fā)事件時,,系統(tǒng)將按照處理函數(shù)的注冊順序調(diào)用各個事件處理函數(shù)。
??? 另外,,對于已注冊事件,,在不需要該事件時可進行注銷事件處理,取消該可連接對象事件對應(yīng)的事件處理函數(shù)的連接,。具體為可連接對象內(nèi)取消接收器接口指針,,接收器對象被刪除(它所保存的事件處理函數(shù)指針和可連接對象指針也就沒了)。
??? 為實現(xiàn)一對多或多對一的情況,,事件發(fā)送方內(nèi)設(shè)置一個以上可連接對象事件,,每個事件對應(yīng)一個可連接對象;事件管理方內(nèi)可創(chuàng)建一個以上接收器,。
??? 為將同一個事件處理函數(shù)注冊到不同對象的事件中,,事件管理方接收器可與一個以上的可連接對象建立關(guān)系;事件發(fā)送方可連接對象可與一個以上事件管理方接收器建立關(guān)系??蓪⑼粋€事件對應(yīng)的多個事件處理函數(shù)注冊,,也就是一個事件可對應(yīng)多個事件處理函數(shù),用于分別執(zhí)行同一事件的不同注冊請求,。
??? 為更好地管理可連接對象狀態(tài),,可連接對象設(shè)置有重載處理,用于作為可連接對象處于可調(diào)用狀態(tài)的“開或關(guān)”,,管理可連接對象是否能夠被調(diào)用,。
??? 在事件管理方第一次注冊某可連接對象時,調(diào)用重載處理,,也就是將可連接對象的調(diào)用狀態(tài)設(shè)置為“開”,;在事件管理方最后一次注銷可連接對象時,調(diào)用重載處理,,將可連接對象的調(diào)用狀態(tài)設(shè)置為“關(guān)”,;沒有重載處理時,執(zhí)行空操作,。其中,可連接對象設(shè)置連接計數(shù)器,,用于統(tǒng)計該可連接對象所建立連接的數(shù)量,,每注冊一次,計數(shù)器加1,;注銷一次,,計數(shù)器減1。當計數(shù)器數(shù)量為零時,,調(diào)用重載處理,,將可連接對象的調(diào)用狀態(tài)設(shè)置為“關(guān)”。
??? 事件發(fā)送方內(nèi)設(shè)有接口指針容器,,用于存儲可連接對象事件的描述信息以及接口指針,。事件管理方內(nèi)的接收器注冊時,通過接口指針容器尋找所需要的可連接對象事件,。這樣具體的尋找方式為枚舉方式,,逐一尋找事件標識,再連接指針將具體事件對應(yīng)的事件標識傳入,,獲得該事件連接點對象的連接接口指針,。
??? 事件管理方設(shè)有與應(yīng)用程序連接的管理接口,用于接收應(yīng)用程序的調(diào)用,,應(yīng)用程序通過該接口把事件處理函數(shù)的指針傳入事件管理方,,事件管理方再去注冊該事件處理函數(shù)。因為事件管理方的注冊、回調(diào)等代碼是自動生成的,,所以需要這個接口與應(yīng)用程序交互,。
??? 事件發(fā)送方分發(fā)事件,事件管理方實現(xiàn)事件處理函數(shù)指針的保存,、與原對象端的連接,、回調(diào)函數(shù)的過程,兩者通過接口建立通信,。其中建立通信應(yīng)包括用戶自定義的接口注冊,,具體步驟如圖2所示;根據(jù)注冊信息進行事件激發(fā)的步驟,,具體步驟如圖3所示,;用于注銷事件處理函數(shù)的注銷步驟,具體步驟如圖4所示,。
?
?
?
?
??? 如圖2所示,,機制的客戶注冊事件處理函數(shù)將完成以下操作:
??? 步驟1:獲得事件管理方接口指針;
??? 步驟2:通過事件管理方接口創(chuàng)建接收器對象(EventHandler),,保存事件處理函數(shù)的指針到該對象中,;
??? 步驟3:利用源對象提供的連接點容器接口中的尋找連接指針函數(shù),找到與該事件對應(yīng)的連接點對象,;
??? 步驟4:通過連接點對象提供的連接點指針接口中的Advise函數(shù),,把事件接收器提供的管理方接口注冊到源對象端;
??? 步驟5:注冊時獲得標識該連接的dwCookie,,保存到接收器對象中,。
??? 如圖3所示,構(gòu)件激發(fā)事件將完成以下操作:
??? 步驟1:枚舉與該事件對應(yīng)的連接點對象中的每個連接,;
??? 步驟2:把事件的參數(shù)打包,,并對每個連接調(diào)用其IDispatch接口中的Invoke函數(shù),以激發(fā)事件,;
??? 步驟3:接收器對象把傳過來的Invoke的參數(shù)解包,,并通過其保存的函數(shù)指針調(diào)用事件處理函數(shù)。
??? 如圖4所示,,客戶注銷事件處理函數(shù)將完成以下操作:
??? 步驟1:通過事件處理函數(shù)的指針和事件的EID(Event ID 事件標識)找到對應(yīng)的接收器對象,;
??? 步驟2:獲得接收器對象保存的標識該連接的dwCookie;
??? 步驟3:利用源對象提供的IConnectionPointContainer接口中的FindConnectionPoint函數(shù),,找到與該事件對應(yīng)的連接點對象,;
??? 步驟4:通過連接點對象提供的IConnectionPoint接口中的Unadvise函數(shù),傳入dwCookie作參數(shù),,注銷事件處理器提供的IDispatch接口,;
??? 步驟5:釋放接收器對象。
??? 基于CAR構(gòu)件的用戶自定義事件機制實現(xiàn)了跨平臺的構(gòu)件開發(fā)和運行環(huán)境,該機制安全可靠,,容錯性好,,并且小型高效。
該機制可運用于嵌入式操作系統(tǒng)圖形系統(tǒng),,操作系統(tǒng)只在有事件發(fā)生時回調(diào)用戶程序的事件處理函數(shù),,不需要消息循環(huán)。用戶進程可以沒有線程,,操作系統(tǒng)在有事件發(fā)生時,,再啟動線程執(zhí)行事件處理函數(shù),從而大大提高了操作系統(tǒng)的效率,。Elastos的圖形系統(tǒng)即采用該機制,。
??? 該機制還可用于嵌入式系統(tǒng)的驅(qū)動程序。用戶程序或操作系統(tǒng)把事件處理函數(shù)注冊到用事件機制編寫的設(shè)備驅(qū)動程序構(gòu)件中,。當有硬件中斷時,,驅(qū)動程序直接回調(diào)用戶程序或操作系統(tǒng)的事件處理函數(shù)。這樣就可以省去用線程定期查詢設(shè)備狀態(tài)的資源,,也使程序編寫變得更簡單,。
參考文獻
[1] Koretide.Elastos2.0Manual.http://www.koretide.com.cn/download/download.php?id=2,2006.
[2] PAN A.COM′s Principle and COM′s Application.The?Tsinghua Press,,1999.
[3] ROGERSON D.Inside COM:Microsoft′s Component Object?Model.Microsoft Press,,1999.
[4] ECKEL B.Thinking in C++(Second Edition).Prentice Hall,2002.
[5] Koretide.CAR′s Manual[M],,2006.
[6] Koretide.Website[EB/OL].http://www.koretide.com.cn
[7] 陳榕,劉藝平.技術(shù)報告:基于構(gòu)件,、中間件的因特網(wǎng)操作系統(tǒng)及跨操作系統(tǒng)的構(gòu)件,、中間件運行平臺(863課題技術(shù)鑒定文件),2003.