我可以通过JNA从Java使用COM吗?
问题描述:
也许我很疯狂,但即使只是为了学习体验,我也开始享受这个想法:我试图通过调用Ole32.dll函数通过JNA来从Java使用COM。根据COM规范,COM接口指针只是指向指向函数指针数组的指针的指针。我想,因为JNA允许调用函数指针,所以我应该可以调用COM接口方法,如果我可以得到VMT(函数指针数组)。我可以通过JNA从Java使用COM吗?
这里是我的IUnknown接口:
@IId("00000000-0000-0000-C000-000000000046")
public interface IUnknown {
int QueryInterface(Guid riid, PointerByReference ppvObject);
int AddRef();
int Release();
}
这里是一些代码来创建一个IUnkown接口,给定一个CLSID:
public static IUnknown createInstance(Guid clsId) {
IId iidA = IUnknown.class.getAnnotation(IId.class);
if (iidA == null)
throw new IllegalArgumentException("Interface needs to be annotated with an IId");
Guid iId = new Guid(iidA.value());
Ole32 ole32 = WindowsJna.OLE32.get();
PointerByReference p = new PointerByReference();
int res = ole32.CoCreateInstance(clsId, null, Ole32.CLSCTX_INPROC, iId, p);
if (res != Ole32.S_OK)
throw new WinApiException(res);
final Pointer interfacePointer = p.getValue();
final Pointer vTablePointer = interfacePointer.getPointer(0);
final Pointer[] vTable = new Pointer[3];
vTablePointer.read(0, vTable, 0, 3);
return new IUnknown() {
public int QueryInterface(Guid riid, PointerByReference ppvObject) {
Function f = Function.getFunction(vTable[0], Function.ALT_CONVENTION);
return f.invokeInt(new Object[] { interfacePointer, riid, ppvObject });
}
public int AddRef() {
Function f = Function.getFunction(vTable[1], Function.ALT_CONVENTION);
return f.invokeInt(new Object[] { interfacePointer });
}
public int Release() {
Function f = Function.getFunction(vTable[2], Function.ALT_CONVENTION);
return f.invokeInt(new Object[] { interfacePointer });
}
};
}
我还是有点新的JNA ,所以我想知道代码是否有意义? Couln't得到它的工作,因为我被困在这个代码被调用之前的一些其他愚蠢的错误。
这种做COM的方式是否会太慢,或者实际上它可能成为从Java实现它的一种可行的方式,尤其是如果在COM的IDispatch中引入一些Java Dynamic Proxies?
我知道JACOB和来自Java的其他COM库,我已经使用过它们。只是尝试一些新的东西,比如我所提到的学习体验。
答
鉴于本机COM全部构建在C(而不是C++)上,如果本机代码使用C或stdcall调用约定,这在技术上将起作用。 JNA为您提供了所需的所有工具,以便与本机内存保持一致,并为函数调用设置堆栈。尽管如此,最终你会想到能够解析typelib并生成实际需要的接口的东西,我相信这是JACOB和com4j所做的。
编辑
JNA现在提供了相当全面的COM支持,包括类型库和事件回调的读数。
我刚刚能够调用IUnknown.QueryInterface :-)。它似乎工作 – 2011-04-12 13:29:15
这看起来不错,你可以发布整个代码? – Rekin 2013-08-22 15:15:31
更多代码在这里:http://blog.abstractinvoke.com/2011/07/using-com-from-java-via-jna/ – 2013-08-27 20:06:53