如何在Java项目中定义并调用C/C++编写的native方法?
开发工具
IntelliJ IDEA 2020 (用来编写java代码)
Visual Studio 2019 (用来编写用C++实现的native方法)
编写测试的java代码
(1)编写代码: 在src目录下新建一个包Package0,在该包中建一个类HelloCPlus。
package Package0;
public class HelloCPlus {
//这是在之前代码的基础之上添加的代码,目的是添加.dll文件
static {
System.loadLibrary("Dllforjavatest1");
}
public native int HelloJava(); //信息
public native int CPlusMax(int... elements); //求最大值
public native int CPlusMin(int... elements); //求最小值
public native int CPlusAccumulate(int... elements); //求累加和
public static void main(String[] args) {
HelloCPlus helloCPlus = new HelloCPlus();
System.out.println("-------");
helloCPlus.HelloJava();
int[] apples = {4,5,6,7,1,2,3};
System.out.println("数组最小值为:"+helloCPlus.CPlusMin(apples));
System.out.println("数组最大值为:"+helloCPlus.CPlusMax(apples));
System.out.println("数组的累加和为:"+helloCPlus.CPlusAccumulate(apples));
}
}
(2)使用命令生成项目头文件,即.h文件。
这里可以有两个步骤:
第一个步骤:
使用“WIN+R”命令输入CMD打开Windows的命令行程序,进入到项目的类目录中,使用命令 javah -classpath E:\Java_learning_project\JNIProgramTest\src -jni Package0.HelloCPlus
即可生成HelloCPlus的.h文件(注:生成的.h文件将会存放在项目的类目录中)
![忽略错误](https://img-blog.csdnimg.cn/20210703225523758.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703225715779.png)
第二个步骤:
先运行main方法,报错没关系,在IDEA中切换到terminal命令窗口,使用命令:javah -classpath out\production\JNIProgramTest -d ./jni Package0.HelloCPlus
,就可以将生成的.h文件置于jni目录中
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703231452554.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
编写C++代码
使用 Visual Studio 2019 编写C++实现的native方法。
(1)新建项目:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703232708139.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703233057831.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703233540727.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
(2)配置头文件:
找到本地电脑JDK1.8安装路径。将路径下的jni.h和jni_md.h文件复制到C++项目路径下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703234825688.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703234925563.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
然后将IDEA创建的头文件Package0_HelloCPlus.h复制到项目路径下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703235650620.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
最后再将这三个文件添加到Visual Studio创建的项目的头文件中。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210703235912875.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
(3)实现C++代码:
首先修改一下Package0_HelloCPlus.h的开头部分:![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704000543237.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
新建C++源文件HelloJava.cpp:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704001023683.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704001154444.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
HelloJava.cpp代码实现如下:
#include "Package0_HelloCPlus.h"
#include "jni.h" //导入两个头文件
#include <iostream>
#include<algorithm>
#include<numeric> //std::accumulate
using namespace std;
//Native调用的方法
/* JNI方法基本格式:JNIEXPORT 返回值类型 JNICALL 方法名(参数列表)
* 方法名规范:Java_包名_类名_方法名
* 参数列表:JNIEnv *env 第一个参数是JNI环境参数,即JNIEnv类型的指针。
* jobject instance 第二个参数是native方法的Java类对象。
*/
JNIEXPORT jint JNICALL Java_Package0_HelloCPlus_HelloJava
(JNIEnv* env, jobject obj)
{
cout << "Hello java,The message is from C++!" << endl;
return 0;
}
JNIEXPORT jint JNICALL Java_Package0_HelloCPlus_CPlusMax
(JNIEnv* env, jobject obj, jintArray jarr)
{
//获取arrays对象的指针
jint* int_arr = env->GetIntArrayElements(jarr, NULL);
//获取数组的长度
jsize len = env->GetArrayLength(jarr);
return *max_element(int_arr, int_arr + len);
}
JNIEXPORT jint JNICALL Java_Package0_HelloCPlus_CPlusMin
(JNIEnv* env, jobject obj, jintArray jarr)
{
//获取arrays对象的指针
jint* int_arr = env->GetIntArrayElements(jarr, NULL);
//获取数组的长度
jsize len = env->GetArrayLength(jarr);
return *min_element(int_arr, int_arr + len);
}
JNIEXPORT jint JNICALL Java_Package0_HelloCPlus_CPlusAccumulate
(JNIEnv* env, jobject obj, jintArray jarr)
{
//获取arrays对象的指针
jint* int_arr = env->GetIntArrayElements(jarr, NULL);
//获取数组的长度
jsize len = env->GetArrayLength(jarr);
return accumulate(int_arr, int_arr + len, 0); //初始值为0
}
(4)配置管理器,生成.dll动态链接库文件。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704002732806.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
使用快捷键<Ctrl+B>或者点击"生成"——>“生成Dll_for_java_test1”,编译项目。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704003505371.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
将dll文件链接到java项目中
有两种方法。第一种:
直接将把生成的.dll文件放入idea的项目根目录下,执行方法。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704014350294.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704010833437.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
第二种:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704011158311.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
在VM options中添加.dll文件的路径:-Djava.library.path="D:\Program Files (x86)\VS_2019\C++projects\Dll_for_java_test1\x64\Debug"
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704011638772.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210704011722874.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzUzNzkzODcw,size_16,color_FFFFFF,t_70)
调试成功。
总结
编写java代码,生成头文件 ——> 引入头文件,编写C++实现代码,生成dll文件 ——> 将dll文件链接到java项目中。
希望这篇文章对你有帮助