【问题标题】:Can I use COM from Java via JNA?我可以通过 JNA 从 Java 使用 COM 吗?
【发布时间】:2011-08-03 08:37:09
【问题描述】:

也许我疯了,但我开始对这个想法感到有趣,即使它只是为了学习经验:我正在尝试通过 JNA 调用 Ole32.dll 函数来使用 Java 中的 COM .根据 COM 规范,COM 接口指针只是指向指向函数指针数组的指针的指针。我想既然 JNA 允许调用函数指针,我应该能够调用 COM 接口方法,如果我可以获得 VMT(函数指针数组)。

这是我的 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 还是有点陌生​​,所以我想知道代码是否有意义?无法让它工作,因为在调用此代码之前我遇到了其他一些愚蠢的错误。

这种执行 COM 的方式会不会太慢,或者它实际上是否可以成为从 Java 执行它的一种可行方式,尤其是如果将一些 Java 动态代理与 COM 的 IDispatch 一起投入使用?

我知道 JACOB 和其他来自 Java 的 COM 库,并且我已经使用过它们。就像我提到的,只是为了学习体验尝试一些新的东西。

【问题讨论】:

  • 我刚刚能够调用 IUnknown.QueryInterface :-)。它似乎工作
  • 这看起来很棒,你能发布整个代码吗?
  • 谢谢。我之前找到了您的代码,并尝试以这种方式使用 TaskBar API。它的效果 - 令我惊讶 - 非常好。
  • 太棒了 :-) 那么我的时间花得很好......

标签: java com jna


【解决方案1】:

鉴于本机 COM 都是基于 C(不是 C++)构建的,如果本机代码使用 C 或 stdcall 调用约定,这在技术上将有效。 JNA 为您提供了使用本机内存和为函数调用设置堆栈所需的所有工具。

不过,最终你会希望得到一些可以解析类型库并生成你实际需要的接口的东西,我相信这就是 JACOB 和 com4j 所做的。

编辑

JNA 现在提供了相当全面的 COM 支持,包括读取类型库和事件回调。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-12
    • 2021-08-30
    • 2014-08-03
    • 2015-06-22
    • 2011-06-11
    • 1970-01-01
    相关资源
    最近更新 更多