在JAVA中调用C++/C代码

JNI是Java Native Interface的缩写,它是JDK的一部分,提供了若干的API实现Java和其他语言的通信(主要是C或C++)。但这种有一个缺点就是使用Java与本地已编译的代码交互,通常会丧失平台可移植性。但有一些情况下,是可以接受的,甚至是必须的。例如使用一些旧的库,或者与硬件、操作系统进行交互等。(这里要注意,JNI也可以让C++代码调用JAVA代码)
接下来我们就借助JNI实现一个简单从JAVA中调用C++代码的HelloWorld。

1. 编写JAVA代码

在JAVA中调用C++/C代码
我们注意到,上图的代码中,出现了 native 关键字,这里,我们先介绍一下 native 关键字:

native关键词修饰的方法是一个原生态方法,方法对应的实现不是在当前文件,而是在其他语言中实现的。 这里编写带有native声明的方法的java文件,就是表明了有对应其他语言实现了这些方法。

2. 生成头文件

先执行 javac 指令,生成对应的 .class 文件
在JAVA中调用C++/C代码
再执行 javah 指令,生成对应的头文件
javah -classpath xx -jni yy
其中 xx 为 src 文件夹的目录
yy 为包名 + class文件名
在JAVA中调用C++/C代码
生成头文件:
在JAVA中调用C++/C代码

3. 创建其他语言的工程

我们这里选择实现C++语言的例子,工程搭建过程如下:
在JAVA中调用C++/C代码
在JAVA中调用C++/C代码

在JAVA中调用C++/C代码
生成项目文件后,我们要导入以下的三个头文件
在JAVA中调用C++/C代码
其中,<喎�"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCmFhX2JiX2NjX0hlbGxvLmijus6q1q7HsCBKQVZBILT6wuvJ+rPJtcTNt87EvP4gam5pX21kLmijutTaamRrsPzE2qOswre+tqO6XEphdmFcamRrMS44LjBfMTUyXGluY2x1ZGVcd2luMzIgam5pLmijutTaIGpka7D8xNqjrMK3vrajulxKYXZhXGpkazEuOC4wXzE1MlxpbmNsdWRlDQo8cD7V4sDv0qrXotLio7rSqtDeuMS1vMjrIEpBVkEgtPrC68n6s8m1xM23zsS8/qO6PGJyIC8+DQo8aW1nIGFsdD0="这里写图片描述" src="/uploadfile/Collfiles/20180811/20180811091055612.png" title="\" />
修改为:
在JAVA中调用C++/C代码

4. 编写C++代码

在JAVA中调用C++/C代码

5. 生成dll文件

在JAVA中调用C++/C代码
在JAVA中调用C++/C代码

6. 编写 JAVA 代码,实现调用 C++ 函数

在JAVA中调用C++/C代码
这里 System.loadLibrary("") 导入 dll 或 so 文件
但我们尝试执行,发现报错:
在JAVA中调用C++/C代码
这里没有 java.library.path ,我们进行配置:
在项目处右键:Properties -》Java Build Path -》Source -》Native library location
在JAVA中调用C++/C代码
在这里配置存放 dll 或 so 的文件目录
在JAVA中调用C++/C代码
切到 Libraries -》 Native library location
在JAVA中调用C++/C代码
在这里配置存放 dll 或 so 的文件目录
在JAVA中调用C++/C代码
再次尝试运行,但是发现还是报错,为什么呢?
在JAVA中调用C++/C代码
这里是因为,生成的dll,是在 win32 的环境下生成的,32位的dll,但是 JDK 是64位的,这里处理的方式有两种,一个是通过 VS 环境下生成 win64 的dll,另外一种方式就是使用32位的 JDK,我这里使用32位的 JDK 重新创建 JAVA 项目,成功运行:
在JAVA中调用C++/C代码