http://liumspace.spaces.live.com/blog/cns!bc24129fc2e42afd!122.entry
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)。
当然,实际的实现更复杂,比如说有一个global table来记录Java wrapper与native的JavaXPCOMInterface之间的关系以避免不必要的多次为同一XPCOM对象建立Java wrapper等。
在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的实现中还实现了reference management,这样在Java code中不再需要去实现如AddRef/Release,系统已经都管理好了。
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中,不适合第三方扩充。