簡體   English   中英

我可以通過JNA從Java使用COM嗎?

[英]Can I use COM from Java via JNA?

也許我瘋了,但是即使是為了學習,我也開始對這個想法感到有趣:我試圖通過JNA調用Ole32.dll函數來從Java使用COM。 根據COM規范,COM接口指針只是指向一個指向函數指針數組的指針的指針。 我以為,由於JNA允許調用函數指針,因此如果可以獲取VMT(函數指針數組),我應該能夠調用COM接口方法。

這是我的IUnknown接口:

@IId("00000000-0000-0000-C000-000000000046")
public interface IUnknown {
    int QueryInterface(Guid riid, PointerByReference ppvObject);
    int AddRef();
    int Release();
}

在給定CLSID的情況下,這是一些代碼來創建IUnkown接口:

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還無法正常工作,因為在調用此代碼之前,我還遇到了其他一些愚蠢的錯誤。

這種使用COM的方式會太慢嗎?或者它實際上會成為從Java來實現的一種可行的方式,特別是如果有人將某些Java動態代理與COM的IDispatch一起使用時?

我了解Java的JACOB和其他COM庫,並且已經使用過它們。 就像我提到的那樣,只是嘗試一些新的學習經驗。

鑒於本機COM都是基於C(而不是C ++)構建的,因此如果本機代碼使用C或stdcall調用約定,則從技術上講這將起作用。 JNA為您提供了用本機內存完成所有功能並為函數調用設置堆棧所需的所有工具。

最終,盡管如此,您最終還是想得到可以解析typelib並生成實際需要的接口的東西,我相信這就是JACOB和com4j所做的。

編輯

JNA現在提供了相當全面的COM支持,包括讀取類型庫和事件回調。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM