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