Hello JNI
1. 编写Java类
定义一个 Java 类HelloNative,为使用的本地方法编写方法声明,指定 native 关键字,HelloNative.java如下所示:
public class HelloNative {
public native void print(String s);
static {
try {
System.loadLibrary("HelloNative");
} catch(UnsatisfiedLinkError e) {
System.err.println( "Cannot load hello library:\n " +
e.toString() );
}
}
public static void main(String[] args) {
new HelloNative().print("Hello World!!!");
}
}
编写后Java代码后要编译HelloNative类:
javac HelloNative.java
2. 编写本地方法
接下来要为以上定义的类编写Java本地接口头文件,可以使用javah来生成对应的头文件:
javah HelloNative
生成的HelloNative.h如下所示:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloNative */
#ifndef _Included_HelloNative
#define _Included_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloNative
* Method: print
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_HelloNative_print
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
下面对头文件中定义的函数进行实现,HelloNative.cpp如下所示
#include "HelloNative.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloNative_print
(JNIEnv * env, jobject arg, jstring instr) {
// get the pointer pointed to UTF encoding string from instr.
const char *str =
(const char *)env -> GetStringUTFChars(instr, JNI_FALSE);
printf("%s\n",str);
// inform the jvm that the native code doesn't need to
// access Java String by str.
env -> ReleaseStringUTFChars(instr, str);
return;
}
其中env指针指向一个函数指针表;jobject指向java中的java对象,相当于this;instr是从Java代码传递过来的String类对象,在本地代码中不能直接读取,需要使用GetStringUTFChars函数进行转换。
3. 编译共享库
编译生成目标文件HelloNative.o:
gcc -fPIC -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -c HelloNative.cpp
编译生成共享库libHelloNative.so.1.0:
gcc -shared -Wl,-soname,libHelloNative.so.1 -o libHelloNative.so.1.0 HelloNative.o
cp libHelloNative.so.1.0 libHelloNative.so
4. 运行
添加共享库所在目录到LD_LIBRARY_PATH环境变量中:
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
java HelloNative
或者在运行时设置java的环境变量java.library.path:
java -Djava.library.path=. HelloNative
5. 后记
关于文中用到或未用到的函数或类型说明,请详见参考资料。文中若有错误或疏漏之处,烦请批评指正。
6. 参考资料
《Java2核心技术》第七版, 第二卷, 第11章, 本地方法.
在 Linux 平台下使用 JNI: http://www.ibm.com/developerworks/cn/java/l-linux-jni/