你的位置:首页 > 操作系统

[操作系统][Android]Linux下JNI简单实现过程


首先编写一个java程序

HelloJNI.java

public class HelloJNI{  public native void displayHelloJNI();//所有native关键词修饰的都是对本地的声明    static{    System.loadLibrary("MyLib");//载入本地库  }  public static void main(String[] args){    new HelloJNI().displayHelloJNI();  }}

 

声明native方法:如果你想将一个方法做为一个本地方法的话,那么你就必须声明该方法为native的,并且不能实现。
System.loadLibrary("MyLib");加载动态库
我们可以这样理解:我们的方法 displayHelloWorld()没有实现,但是我们在下面就直接使用了,所以必须在使用之前对它进行初始化)这里一般是以static块进行加载的。同时需要注意的是System.loadLibrary();的参数“hello”是动态库的名字。

编译
javac HelloJNI.java 得到 HelloJNI.class

生成.h头文件
javah HelloJNI
得到 HelloJNI.h

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class HelloJNI */#ifndef _Included_HelloJNI#define _Included_HelloJNI#ifdef __cplusplusextern "C" {#endif/* * Class:   HelloJNI * Method:  displayHelloJNI * Signature: ()V */JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

 

这个h文件相当于我们在java里面的接口,这里声明了一个Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我们的本地方法里面实现这个方法,也就是说我们在编写C/C++程序的时候所使用的方法名必须和这里的一致


编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法。
test.c

#include<stdio.h>#include"jni.h"#include"HelloJNI.h"JNIEXPORT void JNICALL Java_HelloJNI_displayHelloJNI (JNIEnv *env, jobject obj){  printf("this is a JNI test program!\n");  return;}

 

需要将jni.h(该文件可以在%JAVA_HOME%/include文件夹下面找到)文件引入,因为在程序中的JNIEnv、 jobject等类型都是在该头文件中定义的;另外在第2行需要将HelloWorld.h头文件引入(我是这么理解的:相当于我们在编写java程序的时候,实现一个接口的话需要声明才可以,这里就是将HelloWorld.h头文件里面声明的方法加以实现。当然不一定是这样)。

将test.c编译成动态链接库 当前目录下

gcc -shared -I /home/du/jdk1.7.0_71/include -I /home/du/jdk1.7.0_71/include/linux test.c -o libMyLib.so

 

得到libMyLib.so动态链接库

在HelloJNI.java中我们LoadLibrary方法加载的是“MyLib”,
可我们生成的Library却是libMyLib。这是Linux的链接规定的,
一个库的必须要是:lib+库名+.so。链接的时候只需要提供库名就可以了

运行HelloJNI.java

java HelloJNI

Exception in thread "main" java.lang.UnsatisfiedLinkError: no MyLib in java.library.path

 

java -Djava.library.path=. HelloJNI

 

运行 或者

export LD_LIBRARY_PATH=/home/du/test_code:$LD_LIBRARY_PATHjava HelloJNI

即可获得输出。

 

参考:

Linux(Ubuntu)下JNI入门

Linux下JNI的使用