jni入门

 JNI:Java Native Interface,是Java语言提供的一种通用接口,用于Java代码与本地化代码的交互。所谓本地化代码是指直接编译成的与机器相关的二进制代码,而非Java字节码之类的中间代码。Windows下面的可执行文件,DLL等,Linux下面的可执行文件和SO文件等,都是二进制代码。JNI允许Java语言编写的程序与其他语言编写的程序库(DLL, SO)或可执行文件进行互操作,包括汇编、C、C++。


JNI的开发步骤
  (1)、编写带有native方法的java类
  (2)、使用javac命令编译所编写的java类
  (3)、使用javah命令处理类文件,生成C/C++头文件
  (4)、使用C/C++实现本地方法
  (5)、将C/C++编写的文件生成动态连接库

一、建立java文件
public class testdll {
static{
  System.loadLibrary("goodluck"); //goodluck不用加文件类型
}
public native int getValue();//声明本地方法
public native void setValue(int i);

/**
  * @param args
  */
public static void main(String[] args) {
  testdll test=new testdll();
  test.setValue(10);
  System.out.println(test.getValue()); 
}
}
说明:
1)    在JAVA程序中,首先需要在类中声明所调用的库名称System.loadLibrary( String libname );,在库的搜寻路径中定位这个库。定位库的具体操作依赖于操作系统。在windows下,首先从当前目录查找,然后再搜寻”PATH”环境变量列出的目录。如果找不到该库,则会抛出UnsatisfiedLinkError。
2)      这里加载的是JNI生成的DLL,而不是其他生成的DLL的名称。?在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
3)       还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具体实现。?实现放在C中实现,稍后将做说明。
4)       如果加了static,表明是静态方法。如果不加,表明是一般的方法。加与不加,生成的头文件中有一个参数不同。


二、生成头文件
javac testdll.java  ----生成 testdll.class                
javah testdll       ----生成 testdll.h 头文件   
               
三、建立c文件
打开c编译器,建立一个dll空工程,把testdll.h导入工程中,新建一个test.cpp源文件
在testdll.h,发现里面有两个方法:
/*
* Class:     testdll
* Method:    getValue
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_getValue
  (JNIEnv *, jobject);

/*
* Class:     testdll
* Method:    setValue
* Signature: (I)V
*/
JNIEXPORT jint JNICALL Java_testdll_getValue
  (JNIEnv *, jobject);

JNIEXPORT不用管,第二个单词jint/void是返回值,jint相当于int类型,JNICALL不用管,每一个方法名前都有前缀Java_testll_,前两个参数JNIEnv *和jobject不用管,第二个方法的第三个参数jint就是java文件里的int i。
上面有声明了,现在就要实现这两个方法,编写testdll.cpp文件:

#include "testdll.h"
int i=0;
JNIEXPORT jint JNICALL Java_testdll_getValue
(JNIEnv *, jobject){
return i;
}
JNIEXPORT void JNICALL Java_testdll_setValue
(JNIEnv *, jobject, jint j){
i=j;
}

四、生成动态链接库文件
此时编译会出现error,主要是提示找不到jni.h(这个包含在testdll.h)里,需要我们把jni.h、jni_md.h复制到C:\Program Files\Microsoft Visual Studio\VC98\Include这个目录里(默认安装目录,如果安装VC不是这个目录,请自行找到Include目录)。

在构建之前先作如下操作:
把jni.h、jni_md.h复制到c文件编译器安装目录的Include这个文件夹里,其中ni.h、jni_md.h文件到下面目录去找:
jni.h------------------jdk安装目录\include
jni_md.h------------jdk安装目录\include\win32
然后再编译,构建,就有了test.dll这个动态链接库文件了,把它重命名成goodluck.dll。

五、运行
有两种方法运行:
1. 将goodluck.dll文件复制到testdll.class同目录下  在控制台输入:java testdll
如果goodluck.dll文件位置没放好就会报如下错误

2. 将goodluck.dll文件复制到eclipse中项目名目录下,运行
如果goodluck.dll文件位置没放好就会报如下错误


当goodluck.dll文件位置放正确之后运行程序之后将会得到正确答案:
10
但是。。。
你会郁闷的发现,报错了!!!

不用慌,我们还需要改动几个地方:
将testdll.h 和 testdll.cpp中的两个方法:

JNIEXPORT jint JNICALL Java_testdll_getValue

JNIEXPORT jint JNICALL Java_testdll_getValue

都改为:
JNIEXPORT jint JNICALL  _Java_testdll_getValue

JNIEXPORT jint JNICALL  _Java_testdll_getValue

即在java前加上”_”
 



你可能感兴趣的:(jni)