參考文章《Jni 調試 : eclipse + Vs 聯合調試》發現jna也可以按類似的方法調試,方法如下:
1、復制dll到java工程
cp d:\jna-cpp\build\Debug\demojna.dll d:\jna-java\src\main\resources\win32-x86-64\
然后切記要在eclipse中刷新工程
2、修改java代碼
在Native.loadLibrary的調用前面增加:
System.setProperty("jna.debug_load", "true");
確保調試的時候能夠看到盡可能多的信息
3、設置斷點--java
就設置到System.setProperty("jna.debug_load", "true"); 或者任何調用jna前的代碼
4、設置斷點--c
在vs2015中設置斷點到需要調試的代碼上
5、調試
調試啟動java程序,在斷點斷下來后,切換到vs2015中,選擇調試-附加到進程-javaw.exe
然后跑到eclipse中繼續運行程序,這個時候vs2015就可以斷下來了
如果看到下面的圖片,選擇繼續
注意:無論任何時候修改c代碼,都需要重復第一步工作,否則可能斷不下來了
6、錯誤處理:
Exception in thread "main" java.lang.IllegalStateException: Pointer native@0xdddddddddddddddd already mapped to Proxy interface to native function@0xdddddddddddddddd (com.tencent.evmc.demo.EvmcInterface$evmc_destroy_fn).
Native code may be re-using a default function pointer, in which case you may need to use a common Callback class wherever the function pointer is reused.
這個錯誤僅在debug版本的dll中存在,更改為release就沒有了
7、需要注意的地方
char* 的數據如果是可以打印的,也就是不會中間存在0x00數據,java層就可以直接使用String接收,但是如果不可打印只能使用Point接收,否則會被0x00位置截斷;
如果是java傳遞byte[]給c,那么使用string和Point都是可以的;
size_t 的數據用long或者NativeSize都可以接收,建議用NativeSize,如果用int一定得到錯誤的數據;
java調用c函數的返回值可以是結構體,但是c調用java函數,java函數的返回值如果是結構體總是空值,因此只能返回String,這塊比較奇怪,沒有搞明白
8、jna代碼的自動生成
推薦使用jnaerator,下載最新版本,然后命令行執行:
java -jar jnaerator-0.12-SNAPSHOT-20130727.jar -runtime JNA -mode Maven -mavenGroupId com.test -mavenArtifactId myjna -o code -package com.test.myjna -f -library myjna.dll myjna.h