首先,用IDEA新建一个名为JNITest的项目(命名随意)。
然后src下新建java类 NativeMethod.java
public class NativeMethod {
static {
System.loadLibrary("Calculate"); // 需要加载的dll文件名
}
public native void hello(); // 输出 “Hello! It is native method.”
public native int plus(int m, int n); // 加法
public native int minus(int m, int n); // 减法
}
在该类的java文件上右键,在文件夹中打开。
在打开的文件夹下执行命令行,输入 javah NativeMethod,回车。
会发现,文件夹里多了个同名的头文件。(可能会提示:“错误: 编码GBK的不可映射字符”,是因为有中文,但不会影响文件生成)
接下来打开Visual Studio,新建C++的动态链接库(DLL)项目。
项目命名的时候要注意!记得前面NativeMethod类里面的这段代码吗?
System.loadLibrary("Calculate");
里面的Calculate就是后续需要加载的DLL文件名。创建DLL的项目名也要用这个!
刚建好的DLL项目会自带头文件、源文件。
但是这些文件没什么用。我们需要点击以下步骤:
平台选x64,预编译头改为“不使用”。
删除项目的所有.h和.cpp文件,把java项目中生成的头文件复制到DLL项目。
发现 include 报错?这说明缺少了 jni.h文件。
我们找到本地jdk的安装路径,include文件夹下就有该文件。
我们右键打开项目所在文件夹,把刚刚的jni.h复制到这里。
记住这个路径,回到VS,把 “#include<jni.h>”改成绝对路径。
我们Ctrl键加鼠标左键查看jni.h文件,发现报错,说明缺少 jni_md.h文件。
别急,还是在jdk安装路径,include\win32下就有该文件。
同理,复制到DLL项目根路径下。
把 #include "jni_md.h" 也改成绝对路径。
到此为止,报错问题全解决了。
我们新建源文件main.cpp,并用绝对路径来引用java项目里的头文件。
我们查看这个头文件,红框中的正是java项目里的3个方法。JNIEnv* 和 jobject不用管,任何生成的native方法都会有这两个参数,关键是后面的参数,对应了java项目的native方法参数。
把它们复制到main.cpp,实现这些方法。别忘了把括号里的参数补上。
#include "C:\Users\MagicGuo\IdeaProjects\JNITest\src\NativeMethod.h"
/*
* Class: NativeMethod
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_NativeMethod_hello
(JNIEnv* env, jobject jobj) {
printf("Hello! It is native method.\n");
}
/*
* Class: NativeMethod
* Method: plus
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_NativeMethod_plus
(JNIEnv* env, jobject jobj, jint jint1, jint jint2) {
int result = jint1 + jint2;
printf("%d plus %d is: %d\n", jint1, jint2, result);
return result;
}
/*
* Class: NativeMethod
* Method: minus
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_NativeMethod_minus
(JNIEnv* env, jobject jobj, jint jint1, jint jint2) {
int result = jint1 - jint2;
printf("%d minus %d is: %d\n", jint1, jint2, result);
return result;
}
保存文件,点击运行。
项目会弹窗提示无法启动,不用管。只要下面说生成成功了就行。
打开项目所在文件夹,x64\debug下有个 Calculate.dll 文件。
把它复制到java项目的根路径。
我们新建 Main.java 类文件来运行此方法。
public class Main {
public static void main(String[] args) {
NativeMethod method = new NativeMethod();
method.hello();
method.plus(4,5);
method.minus(12,7);
}
}
代码正常运行。
写这个最容易踩坑的地方就是路径,路径写错或者配置错会浪费很多时间来排查。若有疑问欢迎在评论区指出。