摘要:腳本語言可以通過“黏合”構(gòu)件模塊形成新的應(yīng)用程序。通過分析“和欣”操作系統(tǒng)和CAR構(gòu)件編程模型對(duì)面向構(gòu)件編程的支持,提出了基于CAR構(gòu)件系統(tǒng)的腳本語言通用適配層SCI,探討了一種腳本語言與CAR構(gòu)件自動(dòng)適配的技術(shù),以實(shí)現(xiàn)基于CAR構(gòu)件的腳本動(dòng)態(tài)編程。結(jié)合CAR構(gòu)件技術(shù)與腳本語言,提高應(yīng)用程序的模塊化程度,加速應(yīng)用程序的開發(fā)過程。
關(guān)鍵詞:面向構(gòu)件編程;CAR;腳本語言;元數(shù)據(jù)
中圖法分類號(hào):TP311.5文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1001-3695(2007)01-0110-02
1引言
在面向構(gòu)件的開發(fā)模型中,構(gòu)件完成程序的主要功能和邏輯。大量耗時(shí)、性能重要或復(fù)雜的運(yùn)算被封裝在構(gòu)件內(nèi)部,構(gòu)件只需要暴露給外界簡單的接口以提供服務(wù)。在理論上,構(gòu)件應(yīng)該易于使用和更換,這就提高了應(yīng)用開發(fā)的效率和擴(kuò)展性。可是在已有的一些構(gòu)件系統(tǒng)中,如.NET和Java,卻往往達(dá)不到這種效果。
其中一個(gè)原因,筆者認(rèn)為是開發(fā)構(gòu)件和使用構(gòu)件采用同一種語言。構(gòu)件開發(fā)語言往往是一些功能強(qiáng)大的通用語言,這就從本質(zhì)上決定了這些語言的復(fù)雜性,從而增大了使用構(gòu)件的難度,同時(shí)也容易混淆構(gòu)件與外部應(yīng)用的邊界,弱化了面向構(gòu)件的編程思想。
腳本語言通常具有易學(xué)、易用和開發(fā)高效的特點(diǎn),并且腳本語言是解釋執(zhí)行,容易更改、不需要重新編譯,但是腳本語言一般功能較弱,不易擴(kuò)充,有些腳本語言(如Perl,Ruby等)具有開發(fā)擴(kuò)展庫的功能。但是這些擴(kuò)展庫的開發(fā)方法不具有通用性。
“和欣”[1]設(shè)計(jì)的腳本語言通用適配層SCI (腳本可調(diào)用接口)的成功開發(fā)一定程度上解決了這個(gè)問題。利用構(gòu)件程序集運(yùn)行時(shí)[1,2](Component Assembly Runtime,CAR)構(gòu)件中的元數(shù)據(jù),動(dòng)態(tài)調(diào)用CAR構(gòu)件的方法。CAR構(gòu)件的編寫人員不再需要考慮如何與不同的腳本語言適配,所有的工作都由腳本適配引擎通過SCI自動(dòng)完成。
2“和欣”操作系統(tǒng)和CAR構(gòu)件編程環(huán)境
“和欣”[1]操作系統(tǒng)是國家“863”計(jì)劃的“基于中間件技術(shù)的因特網(wǎng)嵌入式操作系統(tǒng)及跨操作系統(tǒng)中間件運(yùn)行平臺(tái)”的重要成果,是一個(gè)基于構(gòu)件的微內(nèi)核現(xiàn)代操作系統(tǒng)。“和欣”操作系統(tǒng)與其他宏內(nèi)核或微內(nèi)核操作系統(tǒng)(如Linux[3],Mach[4]等)的最大區(qū)別就是將微內(nèi)核模型與基于構(gòu)件技術(shù)的充分結(jié)合,形成了“和欣”操作系統(tǒng)的靈活內(nèi)核架構(gòu)模型。
“和欣”操作系統(tǒng)是一個(gè)微內(nèi)核操作系統(tǒng)。在微內(nèi)核操作系統(tǒng)中,系統(tǒng)的一些服務(wù),如文件系統(tǒng)、TCP/IP協(xié)議棧等是作為一個(gè)與用戶進(jìn)程同等的進(jìn)程為其他用戶進(jìn)程提供服務(wù)。因此,在微內(nèi)核操作系統(tǒng)中,一個(gè)主要的問題就是服務(wù)進(jìn)程與應(yīng)用程序進(jìn)程間的通信問題。通常微內(nèi)核操作系統(tǒng)(如Mach[4]和Minix[5])采用消息機(jī)制作為系統(tǒng)服務(wù)進(jìn)程和用戶進(jìn)程通信的手段。“和欣”操作系統(tǒng)則是采用了更加現(xiàn)代的面向構(gòu)件編程技術(shù)。在面向構(gòu)件編程技術(shù)中,不同進(jìn)程甚至是不同主機(jī)之間的構(gòu)件通信是一個(gè)基本問題。在應(yīng)用領(lǐng)域中,也已經(jīng)有了很多成熟的解決方案,如微軟公司的DCOM[6](分布式構(gòu)件對(duì)象模型)和Java中經(jīng)常使用的RMI(遠(yuǎn)程方法調(diào)用)機(jī)制。“和欣”操作系統(tǒng)將構(gòu)件的跨進(jìn)程通信作為一個(gè)操作系統(tǒng)的基礎(chǔ)設(shè)施做到了內(nèi)核之中。從語義上來說,構(gòu)件的進(jìn)程間通信與消息機(jī)制等價(jià),但是,基于構(gòu)件的通信技術(shù)更加符合現(xiàn)代程序設(shè)計(jì)技術(shù)和規(guī)范,使程序更容易模塊化、更健壯,而且構(gòu)件更容易擴(kuò)充和更換,實(shí)現(xiàn)靈活內(nèi)核。
“和欣”操作系統(tǒng)中使用CAR[1,2]構(gòu)件系統(tǒng),CAR構(gòu)件具有充分的自描述元數(shù)據(jù),具體細(xì)節(jié)在下文介紹。這里只需要說明根據(jù)元數(shù)據(jù)系統(tǒng)能夠自動(dòng)生成構(gòu)件對(duì)象的代理對(duì)象和存根對(duì)象。構(gòu)件跨進(jìn)程的通信模式如圖 1所示。
其中服務(wù)構(gòu)件S運(yùn)行在進(jìn)程A中,首先通過系統(tǒng)調(diào)用將服務(wù)構(gòu)件注冊(cè)在系統(tǒng)中,此時(shí)系統(tǒng)中會(huì)生成一個(gè)S的存根對(duì)象。客戶進(jìn)程B要使用進(jìn)程A中的S服務(wù),通過系統(tǒng)調(diào)用找到S的存根對(duì)象,并且在B中根據(jù)S的元數(shù)據(jù)生成與S具有同樣接口的代理對(duì)象。當(dāng)客戶進(jìn)程調(diào)用S的代理對(duì)象的方法時(shí),代理對(duì)象將調(diào)用傳遞給S存根,存根在進(jìn)程A中啟動(dòng)一個(gè)線程,由該線程調(diào)用被請(qǐng)求的S的方法。為了優(yōu)化這種情況,“和欣”操作系統(tǒng)內(nèi)部給每一進(jìn)程都附加了一個(gè)線程池。
CAR構(gòu)件系統(tǒng)有兩個(gè)主要特征:①使用C++作為實(shí)現(xiàn)語言,具有較好的運(yùn)行性能;②CAR構(gòu)件具有充分的自描述元數(shù)據(jù),系統(tǒng)能夠自動(dòng)為CAR構(gòu)件生成存根和代理對(duì)象。兩者的結(jié)合使CAR構(gòu)件編程系統(tǒng)能夠作為系統(tǒng)開發(fā)的高性能中間件系統(tǒng)。
編寫CAR構(gòu)件首先要編寫一個(gè)構(gòu)件的接口描述文件——CAR文件。CAR文件是CAR構(gòu)件的元數(shù)據(jù)的文本形式,它描述了CAR構(gòu)件中的接口信息,以及接口中每個(gè)方法的信息,包括方法參數(shù)、返回值等,同時(shí)還描述了接口繼承體系的信息。
CAR文件經(jīng)過編譯生成C++代碼框架、文檔框架和二進(jìn)制的CAR構(gòu)件元數(shù)據(jù);使用C++語言實(shí)現(xiàn)CAR構(gòu)件的具體功能;經(jīng)過編譯和打包生成可發(fā)布的CAR構(gòu)件程序集,其中包含了CAR構(gòu)件的代碼、數(shù)據(jù)及自描述元數(shù)據(jù)。這個(gè)過程如圖 2所示。
3采用CAR構(gòu)件的SCI編程模型
將腳本語言調(diào)用CAR構(gòu)件以獲得服務(wù)這一要求進(jìn)行抽象,設(shè)計(jì)出一個(gè)適配層,從而讓腳本語言與構(gòu)件協(xié)同工作。
主要的接口稱為腳本可調(diào)用接口(Script Callable Interface,SCI),SCI本身也是用CAR構(gòu)件編程技術(shù)實(shí)現(xiàn)的,結(jié)構(gòu)如圖 3所示。
從圖3中可以看到,SCI的接口以CAR構(gòu)件的數(shù)據(jù)類型和接口類型為基礎(chǔ),設(shè)計(jì)出對(duì)構(gòu)件方法調(diào)用的抽象,SCI的實(shí)現(xiàn)則以對(duì)應(yīng)的元數(shù)據(jù)為基礎(chǔ)。這種結(jié)構(gòu)一定程度上做到了設(shè)計(jì)與實(shí)現(xiàn)的分離。
SCI接口系統(tǒng)中有三個(gè)主要接口,它們的關(guān)系如圖 4所示。
(1)ISCIModule負(fù)責(zé)加載CAR構(gòu)件,從CAR構(gòu)件程序集中實(shí)例化構(gòu)件對(duì)象,并使之與ISCIObject接口對(duì)象綁定。這個(gè)過程完成了CAR構(gòu)件對(duì)象生命的初始化;接下來,對(duì)象生命周期的維護(hù)和實(shí)際方法調(diào)用工作由ISCIObject接口對(duì)象完成。
(2)ISCIObject接口主要有兩個(gè)方法:①方法GetMethodIndex通過內(nèi)部CAR構(gòu)件對(duì)象的元數(shù)據(jù)查找一個(gè)方法的索引,這個(gè)索引是該方法在對(duì)象虛函數(shù)表[7]中的位置。②方法Invoke接收這個(gè)索引值和一個(gè)參數(shù)數(shù)組,通過查找元數(shù)據(jù)得到實(shí)際對(duì)象方法的入口地址;接著由ISCIParameterNormalizer接口對(duì)象根據(jù)元數(shù)據(jù)完成參數(shù)類型的驗(yàn)證和轉(zhuǎn)換工作;最后,使用一段特殊的匯編語言按照C++語言的約定[7]生成方法調(diào)用棧,跳轉(zhuǎn)到實(shí)際對(duì)象的方法,在方法返回后還要進(jìn)行返回值的處理工作。當(dāng)用戶釋放ISCIObject接口對(duì)象時(shí),它會(huì)自動(dòng)釋放內(nèi)部的CAR構(gòu)件對(duì)象。(3)ISCIParameterNormalizer接口是為了進(jìn)行方法參數(shù)的類型驗(yàn)證和轉(zhuǎn)換。實(shí)際工作中的腳本語言千差萬別,它們所支持的參數(shù)類型和CAR構(gòu)件系統(tǒng)所支持的參數(shù)類型通常也不相同,因此本文提出了一個(gè)參數(shù)正規(guī)化的概念。參數(shù)正規(guī)化的過程主要是腳本語言的參數(shù)類型向CAR構(gòu)件參數(shù)類型轉(zhuǎn)換的過程。腳本引擎通過實(shí)現(xiàn)ISCIParameterNormalizer接口注冊(cè)到ISCIObject接口對(duì)象中來完成參數(shù)正規(guī)化。調(diào)用CAR構(gòu)件對(duì)象方法時(shí),ISCIParameterNormalizer接口對(duì)象完成參數(shù)驗(yàn)證和轉(zhuǎn)換工作,它的主要方法Normalize接收一個(gè)參數(shù)類型數(shù)組和參數(shù)值數(shù)組,輸出一個(gè)符合具體CAR構(gòu)件方法的參數(shù)數(shù)組,或者通知ISCIObject接口對(duì)象無法轉(zhuǎn)換參數(shù)。如果轉(zhuǎn)換失敗,腳本引擎會(huì)將錯(cuò)誤報(bào)告給用戶。
4SCI在JavaScript腳本語言中的應(yīng)用
作為SCI的應(yīng)用舉例,本文將在JavaScript[8]腳本語言中集成SCI。JavaScript腳本語言由Netspace公司發(fā)明,起初主要用于HTML動(dòng)態(tài)編程,它是一種面向?qū)ο蟮哪_本語言,其對(duì)象系統(tǒng)容易擴(kuò)充。本文采用Mozilla瀏覽器項(xiàng)目中的SpiderMonkey[8]子項(xiàng)目對(duì)JavaScript語言的實(shí)現(xiàn)。
在JavasScript腳本語言中集成SCI,首先在JavaScript中添加全局對(duì)象Elastos(“和欣”操作系統(tǒng)的英文名稱),該全局對(duì)象提供了一些系統(tǒng)級(jí)的方法。比如CreateObject,該方法能夠通過CAR構(gòu)件的統(tǒng)一標(biāo)識(shí)符和接口名稱創(chuàng)建出一個(gè)CAR構(gòu)件的實(shí)例,并且使該實(shí)例與SCI對(duì)象綁定。示例JavaScript源程序如下所示:
var aFoo=Elastos.CreateObject(\"www.elastos.com/example/Foo.dll\", \"IFoo\");
aFoo.Say(\"Hello, world!\");
其中,aFoo就是SCI對(duì)象在JavaScript中的表示。當(dāng)調(diào)用aFoo的方法時(shí),腳本引擎將該方法解析為ISCIObject的Invoke方法,從而完成了對(duì)底層CAR構(gòu)件的動(dòng)態(tài)調(diào)用。這樣,就實(shí)現(xiàn)了在JavaScript腳本語言中使用CAR構(gòu)件來進(jìn)行程序開發(fā)。
5結(jié)束語
SCI在本文完成時(shí)已經(jīng)成功地應(yīng)用到了“和欣”操作系統(tǒng)中的XMLGlue項(xiàng)目中,該項(xiàng)目結(jié)合XML,JavaScript和CAR構(gòu)件技術(shù)在應(yīng)用程序用戶界面開發(fā)中得到了大量應(yīng)用。“和欣”操作系統(tǒng)是TDSCDMA中國人第一次擁有的重大通信國際標(biāo)準(zhǔn)的配套工程,將被用在3G手機(jī)中,通過本文的工作,將使更多的人可以通過構(gòu)件的組成完成一個(gè)符合自己需要的應(yīng)用程序,從而提高3G網(wǎng)絡(luò)的應(yīng)用水平。
本文所述工作還有很多后續(xù)工作,充分利用“和欣”操作系統(tǒng)的能力等優(yōu)化工作也在開展。本文基本上只實(shí)現(xiàn)了從腳本語言到CAR構(gòu)件的調(diào)用,還沒有實(shí)現(xiàn)從CAR構(gòu)件到腳本語言的逆向調(diào)用。實(shí)現(xiàn)逆向調(diào)用就可以讓用戶使用腳本語言進(jìn)行簡單的邏輯處理供CAR構(gòu)件回調(diào),從而進(jìn)一步簡化開發(fā)。
參考文獻(xiàn):
[1]Koretide. Elastos 2.0 Operating System Manual[EB/OL]. http://www.koretide.com.cn, 20-04/200506.
[2]Koretide. CAR’s Manual[EB/OL]. http://www.koretide.com.cn, 20-04/200506.
[3]Daniel P Bovet, Marco Cesati. Understanding the Linux Kernel(2nd edition)[M]. Sebastopol:O’Reilly, 2002.2235.
[4]Linda R Walmer, Mary R Thompson. A Programmer’s Guide to the Mach System Calls[EB/OL]. http://www.cs.cmu.edu, 1988/200506.
[5]Andrew S Tanenbaum, Albert S Woodhull. Operating Systems Design and Implementation (2nd edition)[M]. Beijing:Publishing House of Electronics Industry, 1998.7074.
[6]Aiming Pan. COM’s Principle and COM’s Application[M]. Beijing:Tsinghua Press, 1999.302306.
[7]Stanley B Lippman. Inside the C++ Object Model[M]. Wuhan:Huazhong Science and Technology University Press, 2001.129231.
[8]Mozilla. JavaScript C Engine Embedder’s Guide[EB/OL]. http://developer.mozilla.org, 2005.
[9]John K Ousterhout. Scripting: Higher Level Programming for the 21st Century[EB/OL]. http://home.pacbell.net/ouster/scripting.html,1998.
作者簡介:
鄭錕(1981),男,新疆克拉瑪依人,碩士研究生,主要研究方向?yàn)橄到y(tǒng)軟件支撐技術(shù);陳榕(1952),男,北京人,主任,科泰世紀(jì)科技有限公司首席科學(xué)家,主要研究方向?yàn)榫W(wǎng)絡(luò)操作系統(tǒng)、構(gòu)件技術(shù);顧偉楠(1946),男,江蘇無錫人,副主任,教授,主要研究方向?yàn)榍度胧讲僮飨到y(tǒng)。
注:本文中所涉及到的圖表、注解、公式等內(nèi)容請(qǐng)以PDF格式閱讀原文