java 调用DLL动态库(附带源码)_java调用dll动态库
Java 调用 DLL 动态库
1. 项目背景
在 Windows 平台上,很多底层库或第三方 API 以 DLL(Dynamic Link Library,动态链接库) 形式提供。Java 本身不能直接调用 DLL,需要使用 JNI(Java Native Interface,Java 本地接口) 或 JNA(Java Native Access) 进行调用。
本项目主要介绍 如何使用 Java 调用 DLL 文件,并提供 JNI 和 JNA 两种方式 的实现,帮助你根据需求选择合适的方法。
2. 相关知识
2.1 什么是 DLL?
- DLL(Dynamic Link Library,动态链接库) 是 Windows 操作系统中的共享库,多个程序可以动态加载 DLL 以实现代码复用。
- DLL 里面通常包含 函数、类、资源等,可用于扩展软件功能。
2.2 Java 如何调用 DLL?
Java 不能直接调用 C/C++ 编写的 DLL,需要借助:
- JNI(Java Native Interface)
- 需要编写 C/C++ 代码 作为中间层,与 Java 交互。
- 适用于 高性能、复杂逻辑 的场景,但开发复杂。
- JNA(Java Native Access)
- 不需要写 C/C++,直接使用 Java 代码调用 DLL。
- 适用于 简单 API 调用,但性能略逊于 JNI。
2.3 使用场景
3. 实现思路
我们将分别使用 JNI 和 JNA 来调用 DLL:
3.1 JNI 方式
- 编写 Java 代码 声明本地方法。
- 使用
javac
生成.class
文件,然后用javah
生成 C 头文件。 - 编写 C/C++ 代码 实现 DLL 逻辑。
- 编译生成 DLL,让 Java 调用它。
3.2 JNA 方式
- 使用 JNA 库,定义接口映射 DLL 方法。
- 直接调用 DLL,无需额外编写 C 代码。
4. 代码实现
4.1 使用 JNI 调用 DLL
(1)编写 Java 代码
public class JniExample { // 声明本地方法,调用 DLL 中的 nativeMethod public native String nativeMethod(String input); static { System.loadLibrary(\"MyLibrary\"); // 加载 DLL } public static void main(String[] args) { JniExample example = new JniExample(); String result = example.nativeMethod(\"Hello JNI!\"); System.out.println(\"Native Method Returned: \" + result); }}
注意:
System.loadLibrary(\"MyLibrary\")
加载的 DLL 名称是MyLibrary.dll
。
(2)生成 C 头文件
编译 Java 代码:
javac JniExample.java
生成 JNI 头文件:
javah -jni JniExample
此时会生成 JniExample.h
,内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */#include #ifndef _Included_JniExample#define _Included_JniExample#ifdef __cplusplusextern \"C\" {#endif/* * Class: JniExample * Method: nativeMethod * Signature: (Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_JniExample_nativeMethod (JNIEnv *, jobject, jstring);#ifdef __cplusplus}#endif#endif
(3)编写 C 代码
创建 JniExample.c
:
#include \"JniExample.h\"#include #include JNIEXPORT jstring JNICALL Java_JniExample_nativeMethod(JNIEnv *env, jobject obj, jstring input) { const char *inCStr = (*env)->GetStringUTFChars(env, input, NULL); char message[256] = \"JNI Received: \"; strcat(message, inCStr); (*env)->ReleaseStringUTFChars(env, input, inCStr); return (*env)->NewStringUTF(env, message);}
(4)编译并生成 DLL
使用 GCC(MinGW)或 MSVC 进行编译:
gcc -shared -o MyLibrary.dll -I\"%JAVA_HOME%\\include\" -I\"%JAVA_HOME%\\include\\win32\" JniExample.c -Wl,--add-stdcall-alias
(5)运行 Java 代码
java JniExample
输出:
Native Method Returned: JNI Received: Hello JNI!
4.2 使用 JNA 调用 DLL
(1)编写 C 代码
创建 SimpleLibrary.c
:
#include __declspec(dllexport) int add(int a, int b) { return a + b; }
编译生成 DLL:
gcc -shared -o SimpleLibrary.dll SimpleLibrary.c
(2)编写 Java 代码
import com.sun.jna.Library;import com.sun.jna.Native;public class JnaExample { // 定义接口,映射 DLL public interface SimpleLibrary extends Library { SimpleLibrary INSTANCE = Native.load(\"SimpleLibrary\", SimpleLibrary.class); int add(int a, int b); } public static void main(String[] args) { int result = SimpleLibrary.INSTANCE.add(5, 10); System.out.println(\"Result from DLL: \" + result); }}
运行 Java 代码:
java -cp .;jna-5.12.1.jar JnaExample
输出:
Result from DLL: 15
5. 代码解读
JNI 方式
nativeMethod
:Java 声明的本地方法,在 C 代码中实现。javah
生成 C 头文件,用于 C 代码编写。- C 代码实现:使用
JNIEnv
处理字符串并返回新的字符串。
JNA 方式
- 不需要写 C 代码,直接使用
JNA
绑定 DLL 并调用函数。 - 适合简单的 DLL API 交互,例如调用 数值计算、设备控制等 DLL。
6. 项目总结
选择建议:
- 需要高性能或 复杂交互,用 JNI。
- 只是 调用简单 DLL 函数,用 JNA。
7. 结论
本项目展示了 JNI 和 JNA 调用 DLL 的实现,适用于 Java 需要调用 Windows 本地库的场景。