共计 1944 个字符,预计需要花费 5 分钟才能阅读完成。
利用场景
通过 JNI,实现 Java 调用 C ++ 代码
环境
JDK: jdk-17.0.9
mingw-w64: x86_64-8.1.0-release-win32-seh-rt_v6-rev0
操作系统: windows11
实现步骤
1. 申明 native 办法
NativeCommand.java
/**
* # 生成头文件
* javac -encoding UTF-8 -h . NativeCommand.java
* -jni 示意生成 c ++ 头文件,从 Java 10 开始,-jni 选项曾经不再须要了,因为当初 javac -h 默认就会生成 C ++ 的头文件。*
*/
public class NativeCommand {
/**
* 发送命令给 Cpp
* @param command 命令
* @param args 参数
* @return 响应
*/
public native String send(String command, String... args);
}
下面定义了办法public native send(xxx)
2. 生成.h 头文件
执行命令即可(如果是 JDK8,须要应用 javah 命令)javac -encoding UTF-8 -h . NativeCommand.java
jdk17 曾经将 javah 合并到 javac 中了,应用 javac - h 代替 javah 命令
执行实现后当前目录会生成 NativeCommand.h
文件
3. 编写 C ++ 代码
NativeCommand.cpp
#include "NativeCommand.h"
#include <iostream>
JNIEXPORT jstring JNICALL Java_NativeCommand_send
(JNIEnv *env, jobject obj, jstring cmd, jobjectArray args) {
std::cout<<"Cpp copy, Over"<<std::endl;
// std::string hello = "Hello from C++";
return env->NewStringUTF("Over");
}
4. 编译 dll
g++ -Wall -g -I"boot/include" -I"boot/include/win32" -I"boot/include/win32/bridge" -fPIC NativeCommand.cpp -shared -o nativecmd.dll
将输入 nativecmd.dll
其中 boot/ 目录是 jdk17 的装置目录,须要改成本人的
5. 加载 dll
NativeMain.java
public class NativeMain {
static {
// 加载 dll
// 启动参数指定 dll 目录: -Djava.library.path=D:/WorkspaceVsCode/adswarhead
// 打印 java.library.path
// String javaLibraryPath = System.getProperty("java.library.path");
// System.out.println(javaLibraryPath);
// 这里不要加.dll 后缀
System.loadLibrary("nativecmd");
}
public static void main(String[] args) {new NativeCommand().send("xxx", args);
}
}
执行 NativeMain, 切记指定 java.library.path 参数,指向 dll 文件所在的目录, 如果在 IDEA 中执行,能够参考截图:
输入后果:
谬误状况
1. UnsatisfiedLinkError
异样堆栈:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no nativecmd.dll in java.library.path: D:/WorkspaceVsCode/adswarhead
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2429)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:818)
at java.base/java.lang.System.loadLibrary(System.java:1989)
at NativeMain.<clinit>(NativeMain.java:9)
起因:加载 dll 失败
解决办法:查看 -Djava.library.path 参数, 要设置成 dll 所在的目录,示例:-Djava.library.path=D:/WorkspaceVsCode/adswarhead
材料
C++ 启动 JVM 并调用 Java main 办法