在这里呢,只举例如何利用JNA调用动态库DLL文件,具体原理请读者自行查阅。
1,下载依赖的jar包,分别为jna-4.4.0.jar,jna-platform-4.4.0.jar,JNative.jar
2,实例代码
package com.test; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Platform; public class JNA { // 定义接口CLibrary,继承自com.sun.jna.Library public interface testdll extends Library { // msvcrt为dll名称,msvcrt目录的位置为:C:\Windows\System32下面, testdll Instance = (testdll) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), testdll.class); // printf为msvcrt.dll中的一个方法. void printf(String format, Object... args); } public static void main(String[] args) { // 调用printf打印信息 testdll.Instance.printf("yyyyMMdd"); //System.out.println("ddd"); //但是,请注意,这个程序实际上是使用msvcrt.dll这个C运行时库中的printf函数打印出上面这些字符的。 //看,多简单,不需要写一行C代码,就可以直接在Java中调用外部动态链接库中的函数! } }
运行main方法,输出结果为yyyyMMdd
如上述实例代码,注释已经说得很明白了,但是我们在实际开发中总不能把dll文件放到C:\Windows\System32下面吧。所以:
3,把C:\Windows\System32下的msvcrt.dll文件复制到项目的根目录下(src下),为了区分,我们重新命名为msvcrt3.dll ,如下图
然后改造后的实现代码
package com.test; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Platform; public class JNA { // 定义接口CLibrary,继承自com.sun.jna.Library public interface testdll extends Library { //msvcrt3.dll在项目根目录下 testdll Instance = (testdll) Native.loadLibrary("msvcrt3", testdll.class); // printf为msvcrt.dll中的一个方法. void printf(String format, Object... args); } public static void main(String[] args) { // 调用printf打印信息 testdll.Instance.printf("yyyyMMdd"); //但是,请注意,这个程序实际上是使用msvcrt.dll这个C运行时库中的printf函数打印出上面这些字符的。 //看,多简单,不需要写一行C代码,就可以直接在Java中调用外部动态链接库中的函数! } }
运行main方法,输出结果为yyyyMMdd
4,遇到的异常信息
4.1、Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'printf2': 找不到指定的程序。
原因:因为msvcrt3.dll中并没有printf2这个方法,所以报找不到指定的程序
4.2、 %1 不是有效的 Win32 应用程序。
原因:这是因为msvcrt3.dll文件是32位编译出来的,而你用的jdk是64位的,把jdk更换成32位的即可解决