Java调用C语言方法(基于JNI)

何为Native和JNI

1.Native

在Java中存在一个native关键字,被它所修饰的方法是一个本地接口方法。在Java中只需要定义该接口方法,具体操作则可以由其他语言来实现(比如C语言)。

由于Java语言的一些局限性,它不能很好的对操作系统底层进行访问和操作,但是可以通过native先声明本地方法,然后再由其他语言来实现该方法完成对操作系统底层的访问和操作。

2.JNI

Sum公司发布的Java 本地接口(JNI)提供了将Java与C/C++、汇编等本地代码集成的方案,该规范使得在 Java 虚拟机内运行的 Java 代码能够与其它编程语言互相操作。

包括创建本地方法、更新Java对象、调用Java方法,引用 Java类,捕捉和抛出异常等,也允许 Java代码调用 C/C++或汇编语言编写的程序和库。通过使用 Java本地接口编写程序,可以确保代码在不同的平台上方便移植。

环境和编译器

1.windows 10(64位)

2.JDK8(64位)

3.MinGW(64位,Dev C++内置)

4.Eclipse

5.Dev C++

注意事项:打包的DLL文件位数要和操作系统的位数相对应,32位(64位)的DLL(动态链接库)不能在64位(32位)的操作系统上运行,否则在Eclipse进行操作时会抛出”Exception in thread “main” java.lang.UnsatisfiedLinkError”的错误。

Java代码

《Java调用C语言方法(基于JNI)》

1.声明native本地方法

在Java类中先使用native声明本地接口方法,具体操作由C语言来实现。

2.编译类文件

使用Javac命令将该java文件编译为字节码文件,例如:javac Xxx.java。在这里需要注意的是:如果该类在某些包下则需要使用javac -d . Xxx.java命令来编译该java文件,例如本类就需要使用该命令来编译:javac -d . JavaLinkC .java

3.生成头文件

使用javah -jni命令将字节码文件生成为JNI格式的.h头文件供C语言使用,例如:javah -jni Xxx。这里还是需要注意的是:如果该类在某些包下则需要使用该类的全限定名来进行操作,例如本类的生成命令为:javah -jni xyz.tanxiao.link.JavaLinkC。

4.生成结果

《Java调用C语言方法(基于JNI)》

《Java调用C语言方法(基于JNI)》

创建DLL项目

1.在Dev C++中创建DLL项目,如图:

《Java调用C语言方法(基于JNI)》

2.创建main文件

在项目中创建一个main文件,在该文件内实现Java中定义的本地接口方法。

3.导入.h头文件

将之前生成的xyz_tanxiao_link_JavaLinkC.h头文件导入进项目,如图:

《Java调用C语言方法(基于JNI)》

4.xyz_tanxiao_link_JavaLinkC.h中的代码,如图:

其中箭头所指的就是在Java类中声明的native本地方法,这些方法将在main.c文件中被实现。

《Java调用C语言方法(基于JNI)》

5.main.c中的代码,如图:

《Java调用C语言方法(基于JNI)》

6.引入头文件

在main.c中导入xyz_tanxiao_link_JavaLinkC.h头文件,并且实现xyz_tanxiao_link_JavaLinkC.h中声明的方法。需要注意的是:在xyz_tanxiao_link_JavaLinkC.h头文件中声明的方法形数只有参数类型没有没有参数名称,所以需要自己补全参数名。

7.添加外部文件

在我们生成的xyz_tanxiao_link_JavaLinkC.h头文件中引入了#include <jni.h>这个头文件,此头文件就是我们之前提到的JNI,里面定义了一系列的标准,而这个头文件位于JDK的目录中,我们需要将该文件引入到Dev C++的编译环境中,如图:

《Java调用C语言方法(基于JNI)》

8.编译项目

接下来就是紧张刺激的编译环节,到这一步基本上就完成了99.99999%,这激动人心的时刻千万不要手抖呢。

点击四个小方块进行编译操作,下方显示编译结果,如果没有报错则编译成功,如图:

《Java调用C语言方法(基于JNI)》

编译完成后在我们的项目目录中找到编译好的DLL文件,如图:

《Java调用C语言方法(基于JNI)》

9.导入DLL文件

将生成的DLL文件导入到Java项目中,如图:

《Java调用C语言方法(基于JNI)》

10.编写Java代码

导入了DLL文件之后就可以写Java的测试代码了,如图:

《Java调用C语言方法(基于JNI)》

输出结果:

《Java调用C语言方法(基于JNI)》

 

至此我们的跨语言调用完美结束了。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注