2014-07-06 40 views
0

我正在使用期望Callback的JNA界面。我有本地函數的原始地址g,這是我想要作爲回調安裝的函數。我正在調用原生函數f,它需要回調,並且我希望JNA通過將g的地址傳遞給f來將我的原始指針編組爲g作爲回調。這對JNA來說可能嗎?傳遞JNA定義期望回調的原始函數指針?

圖表

這裏是我的意思是一個具體的例子。我正在使用Win32,我想註冊一個窗口類,其默認窗口過程爲DefWindowProc。在普通的過程中,我會做以下用C登記具有默認的窗口過程窗口類:

WNDCLASSEX wcex; 
ZeroMemory(&wcex, sizeof(WNDCLASSEX)); 
wcex.cbSize = sizeof(WNDCLASSEX); 
... 
wcex.lpfnWndProc = LoadLibrary("user32", "DefWindowProcA"); 
... 
ATOM atom = RegisterClassEx(&wcex); 

但是,有時我想用不同的窗口過程來註冊窗口類。在C,我會做以上完全除了:

wcex.lpfnWndProc = MyWindowProc; // Address of my custom window procedure 

希望現在清楚JNA中的困難是什麼。我寫類似於Java代碼:

WNDCLASSEX wcex = new WNDCLASSEX.ByReference(); 
wcex.cbSize = WNDCLASSEX.size(); 
... 
wcex.lpfnWndProc = new MyWindowProc(); // where MyWindowProc implements the Callback interface; 
             // but what if I want to just set it to the address of 
             // DefWindowProcA? 
ATOM atom = User32.RegisterClassEx(wcex); 

CAVEAT

我知道我可以定義的Java功能f兩個備選版本,其中一個需要的Callback和一個這需要Pointer,並將我的地址傳遞給gPointer版本。我也知道我可以爲DefWindowProcA創建一個「包裝器回調」。由於各種原因,這些解決方案不夠。

+0

寫一個適配器。編寫一個調用你的函數指針的回調實現。 –

+0

@David請一直讀到底部的問題。 OP已經表示他們不認爲「包裝回調」方法是可以的。此外,這也是我答案的最初迭代的解決方案,OP明確表示他們想要不同的東西。 –

+0

@Chris我可以讀。只是需要按我說的方式完成。我看不到一個原始指針如何成爲'Callback'。 –

回答

1

爲了能夠使用外部指針作爲Callback,可以按照C程序員所做的方式輸入 - 以聯合方式:使用聯合。

public static class WindowProcUnion extends Union { 
    public Pointer ptr; 
    public WinUser.WindowProc wndProc; 

    public WindowProcUnion(Pointer ptr) { 
     this.ptr = ptr; 
     setType("ptr"); 
     write(); 
     setType("wndProc"); 
     read(); 
    } 
} 

您現在可以閱讀wndProc字段並獲取可用的窗口過程回調。


對於這種使用情況下,DefWindowProc通過User32類實際出口,所以你可以創建一個回調直接調用它:

public static class DefWindowProc implements WinUser.WindowProc { 
    @Override 
    public LRESULT callback(WinDef.HWND hWnd, int uMsg, WinDef.WPARAM wParam, WinDef.LPARAM lParam) { 
     return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam); 
    } 
} 

看一看在Win32WindowDemo class的示例一個窗口過程,代表DefWindowProc

+0

謝謝@Chris Jester-Young。這並沒有回答我的問題,但它確實教給我一些我不知道哪些是非常有用的東西。我做「*真正*想」使用外部指針作爲回調。這是我正在做的工作規範的一部分。但是,並不僅限於此。我希望能夠將* Callback *的一個實例*或*一個函數的原始地址傳遞給*相同*函數,這取決於我目前掌握的內容。 – 0xbe5077ed

+0

我完全理解。在我的工作中,我們有一個案例,我們的第三方庫希望以全局變量的形式進行回調,我必須通過JNA來獲取和設置該變量。我會盡量調整我們的工作代碼以適應您的情況。我可能需要先做一些測試,請耐心等待。 –

+0

當然可以。就像我說過的,我不得不爲這樣的工作代碼做這樣的事情,所以整個主題對我來說並不新鮮。而那時候,我不得不花時間研究JNA的來源,以便弄清楚如何讓它首先出現,所以我很樂意與其他人分享這項技術。 :-D –