Java接触有一阵时间了,一直听说过JNI(Java Native Interface,Java本地接口),以我的理解是Java程序中调用C/C++等等语言编写的动态库之类的方法,具体机制还不是特别清楚,一直也没有用过。最近没事的时候查看了下JDK的源码,发现里面有很多native关键字,于是乎,趁今天没事,就花了下时间来弄个简单的实验,仅仅是通过Java调用C/C++产生的dll动态链接库里面的函数,对于C/C++中使用Java中的类型等,则下一次再深入去研究研究。在这就把所作实验的过程做下记录,以备以后查询所用。
1、工具:
===MyEclipse 8.6 编写Java类
===eclipse-cpp-helios-SR2 产生C/C++的Dll文件
===JDK1.6
2、通过JNI调用本地方法的步骤如下:
2.1、编写调用本地接口的Java类:JNICAller.java
package org.clzps;
public class JNICaller {
static {
System.loadLibrary("libTestJNI");
}
public JNICaller() {}
public native void print();
public native int Add(int a, int b);
}
2.2、通过jdk里面的工具javah产生对应的C/C++头文件.h,命令如下:
javah -jni org.clzps.JNICaller
2.3、在目录下则会产生如下所示的类似文件:org_clzps_JNICaller.h
2.4、启动eclipse-cpp-helios-SR2(关于eclipse-cpp-helios-SR2配置这里不做描述),并且新建一个C Project类型的Shared Library类型的项目,如下图所示:
复制org_clzps_JNICaller.h至新建的项目当中,根据org_clzps_JNICaller.h文件新建对应的org_clzps_JNICaller.c源文件,如下所示:
/* * org_clzps_JNICaller.c * * Created on: 2011-6-20 * Author: Administrator */ #include <jni.h> #include "org_clzps_JNICaller.h" #include <stdio.h> /* * Class: org_clzps_JNICaller * Method: print * Signature: ()V */ JNIEXPORT void JNICALL _Java_org_clzps_JNICaller_print (JNIEnv *env, jobject jobj) { printf("Welcome to JNI's World!"); } /* * Class: org_clzps_JNICaller * Method: Add * Signature: (II)I */ JNIEXPORT jint JNICALL _Java_org_clzps_JNICaller_Add (JNIEnv *env, jobject jobj, jint a, jint b) { int sum = 0; sum = a + b; return sum; }
在Project-->Properties-->C/C++ General-->Paths and Symbols的Includes里面添加jvm.h等相关的头文件,如下图所示:
并且选择顶部Configuration为Release Active,然后Build Project,如果不出错将产生需要的libTestJNI.dll文件,供Java调用;
2.5、将libTestJNI.dll拷贝至System.getProperty("java.library.path")的路径中,关于这个路径请参考其他的资料;
2.6、编写测试JNICaller类得单元测试:
package org.clzps;
import junit.framework.TestCase;
public class TestJNICaller extends TestCase {
public void testCase() {
JNICaller caller = new JNICaller();
caller.print();
assertEquals(30, caller.Add(10, 20));
}
}
2.7,通过mvn test进行测试,出现正确的结果:
3、至此、Java已经通过native成功调用了C/C++编写的动态链接库.dll