IntelliJ idea 2018 平台下JNI编程调用C++算法(一)

参考来源:

http://blog.sina.com.cn/s/blog_b37338430101f3zq.html

http://www.cnblogs.com/xiaocainiao2hao/p/5619862.html

https://blog.csdn.net/aslgm_1/article/details/71514617

huachao1001的专栏:http://blog.csdn.net/huachao1001/article/details/53906237

本文环境:IntelliJ idea2018.2+Visual Studio 2017

项目:JavaWEB+Win32控制台

声明:本人是个新手小白。因为项目是C++算法写的,但是要用网页调用,所以先学习JavaWEB调用C++程序作为尝试。参考了网上的一些教程,结合自己的理解与出现的错误,写成总结日后参考。不足之处请提出。

首先明确本文的步骤:

  1. 在Java中新建一个类。
  2. 生成JNI头文件。(此处有两种方法:2.1手动输入javah命令生成头文件、2.2 一键生成头文件)
  3. 在VS2017下引入头文件。
  4. 将dll添加进JavaWEB工程,成功运行。

1.在Java中新建类

利用IntelliJ  idea新建一个Java工程,在src中新建一个Java类,名称命名“testNative”。之后弹出testNative.java。

在testNative.java中写如下程序:

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第1张图片

函数System.loadLibrary()是加载dll(windows)或so(Linux)库,只需名称即可,无需加入文件名后缀(.dll或.so)。

native关键字将函数sayHello()声明为本地函数,由C/C++实现。具体的实现就在hello.dll(Windows平台)或hello.so(Linux平台)中。

2.生成JNI头文件

  • 2.1 手动输入javah命令生成头文件
  • 2.2 一键生成头文件

2.1 手动输入javah命令生成头文件

JNI生成头文件是通过JDK中提供的javah来完成,javah在 {JDKHome}/bin目录中。用法如下:

javah -jni -classpath (搜寻类目录) -d (输出目录) (类名)
  •  

例如,将E:\Porject\out\com\huachao\java目录中的HelloJNI.class生成头文件,并放入到E:\Project\jni中:

javah -jni -classpath  E:\Porject\out\com\huachao\java -d E:\Project\jni  com.huachao.java.HelloJNI.java
  •  

需要注意的是,使用javah来生成头文件(.h)时,-classpath指定的是编译后的java文件(.class)的目录,而不是源文件(.java)的目录,因此在使用javah指令之前,先build一下项目(或直接运行一下)。此时会生称out目录,所有编译后的文件都会存放在这个目录中。

Build之后:project下的out中多出来production及以下内容。

生成out目录之后的:

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第2张图片

接下来,直接在IDEA的Terminal窗口运行javah,写命令如下:

(没有Terminal窗口的可以在File→Plugins→Terminal 勾选它,点击Apply,点击Restart即可
如果是要启动terminal则必须先做完上面动作,才可以点击Tools→Open Terminal... 来达到打开terminal)

执行javah指令

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第3张图片

javah -jni -classpath (搜寻类目录) -d (输出目录) (类名)

按回车键运行,在终端(Terminal)输入如上命令之后,目录出现了jni文件夹,下面对应有头文件

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第4张图片

打开testNative.h, 函数名称是有规律的,即Java_<>_<类名>_<函数名>

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第5张图片

接下来我们就要实现

至此,生成头文件的第一种方法就结束了。还有另一种一键生成的方法更简单请往下看。

2.2 一键生成头文件

如果目录层次很深,或者是有多个需要生成头文件的class文件,这工作量太大了,当然你可以通过写个小程序来实现。

但是这里有个更便捷的方法。点击File>Settings>Tools>External Tools

External Tools

添加一个新的External Tools:

添加一个先的External Tools

在testNative.java文件中  点击右键>External Tools>Generate Header File

点击生成,可以看到Terminal窗口会自动运行指令。跟2.1小节的指令一模一样。

3.在VS2017下引入头文件

首先打开Visual Studio 2017,新建一个Win32控制台。

Win32项目现在位于“新建项目”对话框中的Windows桌面类别下面,在此类别下面还有一个新的Windows桌面向导,可以创建新的Win32项目

双击 Windows桌面向导,打开如下

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第6张图片

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第7张图片

注意此处不要勾选预编译标头。

初始目录:

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第8张图片

拷贝三个.h文件到VS项目中:

将在Java JDK的安装目录下,我的目录为C:\Program Files\Java\jdk1.8.0_181\include下的jni.h,

与C:\Program Files\Java\jdk1.8.0_181\include\win32下的jni_md.h,

与第一步生成的testNative.h, 一共三个头文件,拷贝到当前VS项目目录下,拷贝之后的目录为:

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第9张图片

testNative.h中的 #include 改为 #include”jni.h”

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第10张图片

在源文件目录下新建.cpp文件,起名main.cpp。写入程序:

#include "testNative.h"
#include "jni.h"//注意添加这句
#include


using namespace std;

JNIEXPORT void JNICALL Java_testNative_sayHello(JNIEnv *env, jobject obj)
{
	cout << "Hello World!" << endl;
	cout << "I come from C++!" << endl;
}

另外,注意,在右侧目录中 右击 解决方案-配置管理器

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第11张图片

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第12张图片

将Debug改成64位,因为我的IntelliJ idea是64位下的。这样改动之后生成的dll可以用在64位平台下。

之后按F5运行,运行成功如图所示。

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第13张图片

显示生成的dll的路径。找到此dll,复制。

4.将dll添加进JavaWEB工程中

将复制得到的dll改名为“hello.dll”,将其拷贝到JavaWeb项目目录下,如图所示:

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第14张图片

之后运行项目,可以在控制台输出中看到如下图所示结果,表示成功。

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第15张图片

5.可能出现的错误

1.【注意事项】:如果你建的C++工程时32位的,当然Win32就是32位的工程,生成的dll只能运行在32位的JDK上。如果你的Java JDK64位的,那么你新建Win32控制台程序后,在项目属性中修改平台为64位即可。若不修改,出现如下错误:

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第16张图片

2.第一次新建Win32控制台选择了预编译表头,如下图所示:

IntelliJ idea 2018 平台下JNI编程调用C++算法(一)_第17张图片

在写main.cpp时候运行出现如下错误:

注意不勾选 预编译标头。

3.【注意事项】testNative.h中的#include改为#include”jni.h”

写在最后:新手起步,不断学习总结。参考了网络资料,有问题提出大家共同交流!

转载请注明出处,谢谢^_^

 

 

 

 

 

你可能感兴趣的:(JavaWEB,JNI,IntelliJ,IDEA,VS2017)