Java中JNI的使用方法

由于项目需要,最近在看jni的东西,刚碰这个东西说起来还是挺复杂的,但是过一遍就明了了,都是数据类型在映射来映射去的,其实是一个很简单的东西。但是如果涉及到了数据的同步及锁的东西,就会比较复杂,这边主要是说一下自己今天看的一些小东西。

编译环境:ubuntu 1204 x64

编译器:jdk1.6.0_45


不多说,直接入主题,下面用一下helloworld.java的示例来说明如何从java代码调用c代码。

jni是为了在java层能够使用本地库或者本地应用程序而推出的一个机制,从jdk1.0就有了,说白了,就是可以让java语言直接调用使用c/c++写的代码。

具本步骤如下:

1、编写java代码,并在代码中声明并调用native方法,要使用native来声明要调用的本地方法我写了一下helloworkd.java的示例。

class HelloWorld {
private native void print();
private native void add(int a, int b);


public static void main(String[] args) {

new HelloWorld().print();
}
static {

System.loadLibrary("HelloWorld");
}
}

static是静态代码块,会首先执行加载库,这个库后面再说。

我们看到代码里面用native声明了一个方法。

2、接下来首先使用javah生成native代码块需要使用的头文件

$ javah -jni HelloWorld

会生成一个头文件。

3、编写native代码,在代码中实现在java层声明的方法,当然,这里面调用的就是c或者c++提供的库函数了,这中间需要通过jni机制来实现,jni机制所做的就是做了一些从java代码到c代码的数据类型的映射,并且封闭了一些方法,我们可以用这些方法来的做一些操作。

下面是具体的代码:

#include
#include
#include "HelloWorld.h"


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

我们看到这边的方法的名称跟在java声明的是不一样的,这个是jni强制要求的命名规则,所以说不要调皮哦,不然编译器可是要闹腾的。

同时,方法里面的参数也是不一样:

第一个参数JNIEnv虽一个指针,这个指向jni封装的一个结构体,在这个结构体里有很多函数指针,这样我们可以在这个方法里面来调用这些方法啦。

第二个参数是jobject的一个对象或者类的引用,具体要看传进来的是什么参数,不多说,大家可以去自己去多看看。

这两个参数是jni的重中之重,jni主要就是这两个东西在作用啦。


4、代码都有了,接下来开始跑起来吧。

整个流程如下:

$javac HelloWorld.java

$javah -jni HelloWorld

$gcc -fPIC -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux HelloWorld.c -o libHelloWorld.so

好了,我们现在跑跑看,其实现在还是跑不通的啦,因为我们还没有设置动态链接库的路径。

$LD_LIBRARY_PATH=.

$export LD_LIBRARY_PATH

ok,现在就让我们来跑一下吧。

$java HelloWorld

这样就可以把代码跑起来了。



--------------------------------------以上均属于原创,转载请声明来源。

你可能感兴趣的:(计算机语言)