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 使用场景
方式 | 适用场景 | 复杂度 | 性能 |
---|---|---|---|
JNI | 需要高性能、复杂 C++ 交互 | 高 | 高 |
JNA | 直接调用简单 DLL 函数 | 低 | 较高 |
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 <jni.h>
#ifndef _Included_JniExample
#define _Included_JniExample
#ifdef __cplusplus
extern "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 <stdio.h>
#include <string.h>
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 <stdio.h> __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 | 复杂 C/C++ 库交互,高性能场景 | 高 | 速度快,可完全控制 | 需要编写 C 代码 |
JNA | 调用简单 DLL API | 低 | 代码少,易维护 | 性能稍逊 JNI |
选择建议:
- 需要高性能或 复杂交互,用 JNI。
- 只是 调用简单 DLL 函数,用 JNA。
7. 结论
本项目展示了 JNI 和 JNA 调用 DLL 的实现,适用于 Java 需要调用 Windows 本地库的场景。
更多推荐
所有评论(0)