Java使用JNA調用DLL
1.准備
1.JDK環境
2.Eclipse
3.JNA包
下載JNA包:
(1).JNA的Github:https://github.com/java-native-access/jna
(2).下載JNA包:
https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna/4.0.0/jna-4.0.0.jar
https://maven.java.net/content/repositories/releases/net/java/dev/jna/jna-platform/4.0.0/jna-platform-4.0.0.jar
4.需要調用的DLL(注意JDK版本位數要與DLL一致)
本文使用的DLL下載:
Dll2x86.dll:https://github.com/XiangJinPeng/NetworkFileStorage/raw/master/ProgrammingLanguage/C and C/Dynamic Link Library and Static Link Library/Files/Dll2x86.dll
Dll2x64.dll:https://github.com/XiangJinPeng/NetworkFileStorage/raw/master/ProgrammingLanguage/C and C/Dynamic Link Library and Static Link Library/Files/Dll2x64.dll
Dll2的編寫請參考我的另一篇博客:https://www.cnblogs.com/xiangjinpeng/p/10192888.html
2.Java和C的數據類型對照表
Java中的數據類型和C中的數據類型聲明關鍵字有所不同,在java代碼中需要使用Java類型來代替C類型,下表為Java類型和C類型對照表。
Java數據類型與C數據類型對照表
3.編寫調用系統DLL的Java代碼
1.在Eclipse中新建Java工程
2.把jna-4.0.0.jar加入到工程的庫中
3.新建Java類HelloWorld並輸入如下代碼
//導包
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class HelloWorld {
/*需要定義一個接口,繼承自Library 或StdCallLibrary。
默認的是繼承Library ,如果動態鏈接庫里的函數是以stdcall方式輸出的,那么就繼承StdCallLibrary,比如kernel32庫。
*/
public interface CLibrary extends Library {
//加載msvcrt.dll庫,此處不需要后綴.dll或.so
CLibrary INSTANCE = (CLibrary)
Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"),
CLibrary.class);
//對msvcrt.dll中需要使用的printf函數進行聲明
void printf(String format, Object... args);
}
public static void main(String[] args) {
//使用printf函數
CLibrary.INSTANCE.printf("Hello, World\n");
for (int i=0;i < args.length;i++) {
CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
}
}
}
運行程序,如果沒有帶參數則只打印出“Hello, World”,如果帶了參數,則會打印出所有的參數。
4.編寫調用自己創建的DLL的代碼
1.新建Java工程
2.把jna-4.0.0.jar加入到工程的庫中
3.把需要使用的dll文件放入到java工程目錄下的bin目錄下
4.新建java類TestDll並輸入如下代碼:
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
public class TestDll {
public interface CLibrary extends Library{
//此處我的jdk版本為64位,故加載64位的Dll
CLibrary INSTANCE = (CLibrary)Native.loadLibrary("Dll2x64",CLibrary.class);
//Dll2x64中定義的函數
double Add(double a,double b);
}
public static void main(String[] args) {
System.out.println("3+4=Add(3,4)="+CLibrary.INSTANCE.Add(3,4));
}
}
輸出結果:
5.出現Exception in thread "main" java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 應用程序,錯誤的解決辦法。
如果出現下面的錯誤:
是因為jdk的位數與dll的位數不一致,換成一致的便可。