我得到以下代码,通过JNA将自定义dll嵌入到我们的Java代码中:
public interface MyLibrary extends Library {
MyLibrary INSTANCE = (MyLibrary) Native.loadLibrary("my_helper", MyLibrary.class);
interface render_t extends Callback {
void callback(int id, int type, int dirty_rects_lenght, Pointer dirty_rects, Pointer buffer, int width, int height);
}
int init();
int createApp(String param, render_t callback);
}
和这个头文件:
extern __declspec(dllexport) int __cdecl init(void);
struct rect_t {
int x;
int y;
int width;
int height;
};
typedef void (__cdecl *render_t) (int id, int type, int dirty_rects_lenght, void* dirty_rects, const void *buffer, int width, int height);
extern __declspec(dllexport) int __cdecl createApp(char *param, render_t render_callback);
代码在linux和osx下运行良好。 DLL使用msvc正确构建,dumpbin也显示所有导出。使用JNA时,init调用正在工作,但是一旦我们调用回调函数“createApp”,它就会崩溃并使用invalid_memory_access。我假设这是因为JNA传递的回调的调用约定,但我不知道如何更改此调用约定。我已经尝试将所有__cdecl转换为__stdcall以使用Windows调用约定,并且还将JNA的库和回调接口分别更改为stdcalllibrary和stdcallcallback,但它会产生相同的错误。
操作系统:Windows 8.1 x64, Java:8 x64, JNA:4.1.0
堆栈跟踪:
Exception in thread "main": java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:383)
at com.sun.jna.Function.invoke(Function.java:315)
at com.sun.jna.Library$Handler.invoke(Library.java:212) <1 internal calls>
at mp.app.MyApp.<init>(MyApp.java:34)