JNI入门

来源:互联网 发布:约瑟夫环递推java 编辑:程序博客网 时间:2024/05/17 18:25

JNI是Java Native Interface的缩写,中文即JAVA本地调用。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是它并不妨碍你使用其他语言,只要调用约定受支持就可以了。

通常有以下几种情况我们需要使用JNI来实现:

1.标准的java类库没有提供你的应用程序所需要的功能,通常这些功能是平台相关的。

2.你希望在java程序中使用一些已经有的类库或者应用程序,而他们并非用java语言编写的。

3.程序的某些部门对速度要求比较苛刻,你选择用汇编或者C语言来实现,并在java语言中调用他们。

关系如下图所示:


一般书写分以下几步进行:

 1.编写带有native声明的方法的java类

 2.使用javac命令编译缩写的java类,然后使用javah + java类名生成h头文件

 3.使用C\C++实现本地方法

 4.将C\C++编写的文件生成动态链接库

 5.运行程序,OK。

下面演示一个示例程序HelloWorld。

 1.编写java类

    首先,我们在硬盘上建立一个文件夹hello作为我们的工作目录,然后编写java代码,命名为HelloWorld.java,如下所示:

class HelloWorld {   public native void displayHelloWorld();//所有native关键词修饰的都是对本地的声明   static {      System.loadLibrary("hello"); //载入本地库   }   public static void main(String[] args) {      new HelloWorld().displayHelloWorld();   }}
注重我们的displayHelloWorld()方法的声明,它有一个关键字native,表明这个方法使用java以外的语言实现。方法不包括实现,因为我们要用c/c++语言实现它。

注重System.loadLibrary("hello")这句代码,它是在静态初始化块中定义的,系统用来装载hello共享库,这就是我们在后面生成的hello.dll(假如在其他的操作系统可能是其他的形式,比如hello.so)
 2.编译java代码

    首先安装java jdk,我安装在C盘下,然后设置环境变量:

1.打开我的电脑--属性--高级--环境变量
 
2.新建系统变量JAVA_HOME 和CLASSPATH

           变量名:JAVA_HOME   变量值:C:\Program Files\Java\jdk1.7.0

           变量名:CLASSPATH   变量值:.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;

  3. 选择“系统变量”中变量名为“Path”的环境变量,双击该变量,把JDK安装路径中

bin目录的绝对路径,添加到Path变量的值中,并使用半角的分号和已有的路径进行分隔。

变量名:Path 变量值:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

          打开命令行,进入hello目录下,输入命令javac HelloWorld.java,生成HelloWorld.class文件,如下图:

     

3.生成h文件

   输入命令 javah HelloWorld, 生成h文件,如下图所示:

   

文件的内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloWorld */#ifndef _Included_HelloWorld#define _Included_HelloWorld#ifdef __cplusplusextern "C" {#endif/* * Class:     HelloWorld * Method:    displayHelloWorld * Signature: ()V */JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
(这里我们可以这样理解:这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致)。

4.编写本地实现代码

   代码:

#include <jni.h>#include "HelloWorld.h"#include <stdio.h>JNIEXPORT void JNICALLJava_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) {   printf("Hello world!\n");  return;}
注意代码中的第1行,需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、 jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入(我是这么理解的:相当于我们在编写java程序的时候,实现一个接口的话需要声明才可以,这里就是将HelloWorld.h头文件里面声明的方法加以实现。当然不一定是这样)。然后保存为 HelloWorldImpl.c就ok了。

5.生成动态库

   这里以在Windows中为例,需要生成dll文件。在保存HelloWorldImpl.c文件夹下面,使用VC的编译器cl成。 

   cl -I“%JAVA_HOME%\include” -I“%JAVA_HOME%\include\win32” -LD HelloWorldImpl.c -Fehello.dll

   注意1:生成的dll文件名在选项-Fe后面配置,这里是hello(中间没有空格),因为在HelloWorld.java文件中我们loadLibary的时候使用的名字是hello。当然这里修改之后那里也需要修改。另外需要将-I%java_home%\include -I%java_home%\include\win32参数加上,因为在第四步里面编写本地方法的时候引入了jni.h文件。

     注意2:使用cl编译器时我们也需要配置一下环境变量:

   如果你是把VC安装在默认路径,那么要把操作系统的默认路径(即PATH)设置为以下四个路径,用分号隔开
   C:\Program Files\Microsoft Visual Studio\Common\Tools\WinNT
   C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin
   C:\Program Files\Microsoft Visual Studio\Common\Tools
   C:\Program Files\Microsoft Visual Studio\VC98\bin

    新建环境变量include,变量值为C:\Program Files\Microsoft Visual Studio\VC98\include

    新建环境变量lib,变量值为C:\Program Files\Microsoft Visual Studio\VC98\lib

    保存。

    编译完成后,会生成hello.dll文件,如下图所示:

    

6.运行程序

   将hello.dll复制到工作目录下,运行java HelloWorld,输出Hello World!如下图所示:

   

   

原创粉丝点击