我正在使用期望Callback
的JNA接口。我有一个本机函数g
的原始地址,这是我想要作为回调安装的函数。我正在调用本机函数f
,它需要一个回调,我希望JNA将我的原始指针编组为g
作为回调,只需将g
的地址传递给{{ 1}}。这可能与JNA有关吗?
例证
这是我的意思的具体例证。我正在使用Win32,我想注册一个窗口类,其默认窗口过程为f
。在普通课程中,我将在C中执行以下操作以注册具有默认窗口过程的窗口类:
DefWindowProc
但是,有时我想注册一个具有不同窗口过程的窗口类。在C中,除了:
之外,我会做到以上所述WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
...
wcex.lpfnWndProc = LoadLibrary("user32", "DefWindowProcA");
...
ATOM atom = RegisterClassEx(&wcex);
希望现在很清楚JNA的难点在于什么。我正在编写类似于:
的Java代码wcex.lpfnWndProc = MyWindowProc; // Address of my custom window procedure
CAVEAT
我知道我可以在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);
的两个备用版本,其中一个版本需要f
,其中一个版本需要Callback
,并传递我的地址到Pointer
到g
版本。我也知道我可以为DefWindowProcA创建一个“包装器回调”。由于各种原因,这些都不是充分的解决方案。
答案 0 :(得分: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
的窗口过程示例。