http://liumspace.spaces.live.com/blog/cns!bc24129fc2e42afd!122.entry
JavaXPCOM
JavaXPCOM基于一套與Eclipse
SWT不同的思路。在JavaXPCOM中,每一個XPCOM interface有一個對應(yīng)的Java interface,注意這里是Java
interface,而不是Java class。那么,在JavaXPCOM中怎么生成一個XPCOM對象的Java
wrapper呢?在JavaXPCOM中,巧妙地使用了reflection。對每一個XPCOM對象,會生成一個
Proxy 來作為Java wrapper,這個Proxy對象實現(xiàn)XPCOM對象所實現(xiàn)的interface。然后這個Proxy把Java interface中的方法調(diào)用再delegate到一個JavaXPCOM提供的
XPCOMJavaProxy(實現(xiàn)
InvocationHandler)上。
這
里有幾個問題:1。系統(tǒng)根據(jù)一個XPCOM對象的指針,怎么知道這個XPCOM對象實現(xiàn)了什么XPCOM接口?再怎么根據(jù)這個XPCOM接口找到對應(yīng)的
Java interface來生成Proxy?2。XPCOMJavaProxy怎么把一個Java調(diào)用再映射到底層的XPCOM調(diào)用上?
JavaXPCOM是這樣實現(xiàn)的:
- 對每一個XPCOM對象的指針,知道其實現(xiàn)的interface的IID。
- 使用nsIInterfaceInfoManager來reflect 這個IID,得到這個interface的meta data(nsIInterfaceInfo)
- 將這個XPCOM對象的指針及nsIInterfaceInfo組合在一起,放在一個JavaXPCOMInterface的數(shù)據(jù)結(jié)構(gòu)里。
- 用這個JavaXPCOMInterface結(jié)構(gòu)的指針來構(gòu)建XPCOMJavaProxy(java
wrapper)。構(gòu)建XPCOMJavaProxy對象時(XPCOMJavaProxy#createProxy(Class
aInterface, long aXPCOMInterface))有兩個參數(shù),第一個為這個proxy實現(xiàn)的Java
interface。這個Java interface的名字由"org.mozilla.xpcom" + (XPCOM interface
name)得來。
- 當XPCOMJavaProxy上的方法被調(diào)用時,native
code會得到方法名、參數(shù)數(shù)組以及JavaXPCOMInterface的指針。從JavaXPCOMInterface可以得到
nsIInterfaceInfo,通過nsIInterface里所包含的meta data,可以得到這個方法在virtual
table中的位置。同時meta
data還會包含信息說明每個參數(shù)的數(shù)據(jù)類型,根據(jù)這個信息,可以把每個參數(shù)marshall成一個nsXPTCVariant結(jié)構(gòu)。
- 通過xptcall,就可以完成對virtual table中的方法的調(diào)用。
- 對方法調(diào)用的結(jié)果,可以再根據(jù)meta
data來unmarshall成Java對象。如果某個out參數(shù)或return參數(shù)是一個XPCOM對象,在meta
data中會描述這個參數(shù)的interface的IID,那么又可以象第一步一樣來對其生成Java wrapper(XPCOMJavaProxy)(nsJavaXPCOMBindingUtils.cpp#GetNewOrUsedJavaObject)。
當然,實際的實現(xiàn)更復雜,比如說有一個global table來記錄Java wrapper與native的JavaXPCOMInterface之間的關(guān)系以避免不必要的多次為同一XPCOM對象建立Java wrapper等。
在Java中實現(xiàn)COM/XPCOM組件(component)
前面討論了怎么從Java中調(diào)用COM/XPCOM中的組件,接下來討論怎么用Java語言來實現(xiàn)COM/XPCOM組件。
JavaXPCOM
?JavaXPCOM中的支持還是依賴了type
information,這是有了這個依賴,JavaXPCOM中實現(xiàn)XPCOM組件要容易得多。在JavaXPCOM中,只需要這個Java對象實現(xiàn)了
所需要實現(xiàn)的XPCOM interface所對應(yīng)的Java interface即可。
- 當一個Java object作為參數(shù)傳給某個XPCOM方法時,native code會通過這個方法的meta data,知道這個參數(shù)應(yīng)該是一個XPCOM對象。
- native code會檢查這個Java object是不是一個Java wrapper,如果是,那么可以直接從這個Java wrapper知道它所wrap的XPCOM對象。
- 接下來會檢查是不是已經(jīng)給這個Java object生成過stub,如果沒有則生成一個nsJavaXPTCStub。nsJavaXPTCStub
會根據(jù)meta data生成virtual table,而且當virtual table中的方法被調(diào)用時,會根據(jù)meta
data知道被調(diào)用方法的名字,再根據(jù)這個名字到Java object中通過reflect找到對應(yīng)的Java方法并調(diào)用它。
另外JavaXPCOM的實現(xiàn)中還實現(xiàn)了reference management,這樣在Java code中不再需要去實現(xiàn)如AddRef/Release,系統(tǒng)已經(jīng)都管理好了。
JavaXPCOM
優(yōu)點:
- 每個XPCOM interface對應(yīng)到Java中還是interface。
- 支持Java的garbase collection。在XPCOMJavaProxy中,重載了finalize()方法,所以Java programmer不需要再去調(diào)用Release。
- 增加新的XPCOM interface容易。只需在org.mozilla.xpcom這個package中增加相應(yīng)的Java interface即可。
- Java interface可以通過工具自動生成。
- 用Java實現(xiàn)XPCOM組件非常簡單。
缺點:
- 由于實現(xiàn)依賴nsIInterfaceInfoManager,也就依賴typelib。這樣一來,方法調(diào)用不能象Eclipse SWT中一樣直接轉(zhuǎn)換為virtual table調(diào)用,效率要明顯低一些。另外,只能支持那些支持typelib的interface。
- 雖然增加新的XPCOM interface容易,但這個interface必須放在org.mozilla.xpcom這個package中,不適合第三方擴充。