第二部分 JNI的简单使用——从Hello World开始认识JNI
这里有一个名为 TestMain 的主程序,
调用其下名为 NativeMethod 类的两个名为 NativeHello 和NativeWorld的本地方法
分别打印输出 “Hello” 和 “World” 字符。
具体步骤如下(环境为 Ubuntu 12.04 LTS + JDK 1.7 ):
1. 创建 TestMain.java 的主程序
//:TestMain.java
public class TestMain {
static {
System.loadLibrary("NativeTest"); // 注意:这里定义了我们稍后要用到的共享库名称
}
public static void main(String[] args) {
NativeMethod nm = new NativeMethod(); //调用类和方法就不用多说了吧
nm.NativeHello();
nm.NativeWorld();
}
}
和 NativeMethod.java 的类
//:NativeMethod.java
public class NativeMethod {
public native void NativeHello(); // 这里的“native”表明了是“本地“方法,稍后用C实现
public native void NativeWorld();
}
2. 使用JDK编译生成 TestMain.class 和 NativeMethod.class
$ javac TestMain.java
3.使用JNI生成可以被C调用的头文件 NativeMethod.h
$ javah -jni NativeMethod
4.接下来我们可以查看 NativeMethod.h
/* DO NOT EDIT THIS FILE - it is machine generated */ 注意:这是我们利用JNI生成的头文件,只能查看,不要修改。
#include <jni.h>
/* Header for class NativeMethod */
#ifndef _Included_NativeMethod
#define _Included_NativeMethod
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: NativeMethod
* Method: NativeHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_NativeMethod_NativeHello // 这是我们定义的第一个本地方法(函数),接下来编写C文件需要调用
(JNIEnv *, jobject); // 必要的两个参数
/*
* Class: NativeMethod 类名
* Method: NativeWorld 方法名
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_NativeMethod_NativeWorld // 这是我们定义的第二个本地方法
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
5.编写两个C文件用于打印输出 “Hello World”
/* TestOne.c */
#include <stdio.h>
#include "NativeMethod.h"
JNIEXPORT void JNICALL
Java_NativeMethod_NativeHello (JNIEnv *env, jobject jObj) // 这里调用的函数就是我们刚刚从NativeMethod.h文件中获得的
{
printf("Hello "); // 打印输出语句
}
/* TestTwo.c */ // 第二个C文件名为TestTwo.c
#include <stdio.h>
#include "NativeMethod.h"
JNIEXPORT void JNICALL
Java_NativeMethod_NativeWorld (JNIEnv *env, jobject jObj)
{
printf("World\n");
}
6. 使用gcc编译链接两个C文件生成共享库 libJNITest.so 以便稍后供Java调用
$ gcc -I /opt/java/jdk1.7.0_45/include/linux/ //链接jdk的路径 -I /opt/java/jdk1.7.0_45/include/ -fPIC -shared -o libNativeTest.so TestOne.c TestTwo.c // 注意:这里共享库的文件名需要在此前定义的基础上加lib前缀
7. 运行此前生成的 TestMain.class 就可以看到程序正常运行了:
$ java -Djava.library.path='.' TestMain // 注意:因为我的文件都在当前目录下,所以路径为'.'