zsl-oo7

JNI 原理与入门(一)

JNI = Java Native Interface 

是java调用C语言用的

是java调用 “用C语言代码编译出来的库” 用的

因为用C语言编写的程序是不可移植的,是平台相关的,所以这种代码一般叫做Native Code

举例来说,同C语言在Windows上写了一个HelloWorld,用VC编译成了dll,这个dll拿到Linux上是运行不起来的。

这就是为什么叫做 “Native” Interface了

其实只要符合JNI,其他语言的代码写的平台相关的库,也可以被java调用,不过一般是用作调C/C++的


====================================


例一 HelloWorld:


1、用记事本写一个最简单的HelloWorld.java , 不过其中打印“HelloWorld”那句话交给C语言去完成,别再System.out.println()

public class HelloWorld {
public native void displayHelloWorld();
static {
System.loadLibrary("hello");
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld();
}
}

注1:public native void displayHelloWorld(); 这句话把displayHelloWorld()方法声明为native的,也就是说这个方法由C语言的库来提供,我们不要去实现它。那么C语言的库在哪里呢?看注2。
注2:System.loadLibrary("hello"); 这句话的意思就是加载C语言的hello这个库,这个库在Windows上可以是一个dll文件,一会儿我们会写相应的C代码去实现displayHelloWorld(),并编译成dll文件供java使用。

注3:System.loadLibrary("hello"); 这句话一般写在static块里,static{}不是这篇的重点,不解释


2、我们先把这个HelloWorld.java编译成class字节码

javac HelloWorld.java


3、编译出来HelloWorld.class后,我们要生成一个C语言需要用到的头文件,这个可以看做是C和java交互的中间件。javah命令可以自动生成这个头文件,命令是:

javah HelloWorld

注1:保证执行javah命令的目录中,存在HelloWorld.class

注2:不要写成 javah HelloWorld.class

执行完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 __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif




4、下面我们用C语言来实现displayHelloWorld(),记事本新建一个文件叫HelloWorldC.c,内容如下:

#include"jni.h"
#include"HelloWorld.h"

JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env,jobject obj)
{
printf("Helloworld!\n");
return;
}

注1:头两行的include必须要有,其中第二行的.h文件是我们用javah工具生成的,第一行的jni.h是java sdk提供给我们的,具体路径在:%java_home%\include 

注2:我们这个c文件干的所有事儿,其实就是实现了HelloWorld.h中的那个方法,实现的也很简单,就是printf一句话。这个函数名和参数我们可以去HelloWorld.h里复制。


5、写好c文件之后,我们编译它,生成dll。

注意,生成的dll文件名必须叫hello.dll,因为我们的java代码里load的就是“hello”(System.loadLibrary("hello");)

如何把c文件编译生成dll不是本文的重点,我们必须得到hello.dll就对了。关于如何编译,对于没有安装VC++的Windows机器,要么就安装一个,要么就参考这篇文章


6、好了,在保证hello.dll和HelloWorld.class在同一目录下的时候,我们运行java HelloWorld,就可以看到打印输出了

评论

热度(2)