基本流程:
1. 创建一个类(HelloWorld.java)
2. 使用 javac 编译该类
3. 利用 javah -jni 产生头文件
4. 用本地代码实现头文件中定义的方法
5. Run
备注:在一个特定环境中,写本地实现的过程是不同的(如 Android)。
1.创建HelloWorld
public class HelloWorld { // 1.静态块,类加载时,加载一次 static { System.loadLibrary("HelloWorld"); } // 2.使用native关键字声明native方法 private native void print(); public static void main(String[] args) { new HelloWorld().print(); } }
2.编译,生成.class文件
javac -encoding utf-8 HelloWorld.java
PS. -encoding utf-8 可选
3.生成.h文件
javah HelloWorld
注意事项:
1.没有后缀.class
2.如果有包名,要带上包名。比如 personal.hbl.HelloWorld
生成的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: print * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
本地方法:
JNIEXPORT void JNICALL Java_HelloWorld_print (JNIEnv *, jobject);
第一个参数是指向 JNIEnv 结构的指针。
第二个参数,为 HelloWorld 对象自身,即 this 指针。
JNIEnv 是 JNI 核心数据之一,地位非常崇高,所有对 JNI 的调用都要通过此结构。
编写实现:
#include <jni.h> #include <stdio.h> #include "HelloWorld.h" JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj){ printf("Hello World! "); return; }
请注意:"jni.h"文件必须被包含,该文件定义了 JNI 所有的函数声明和数据类型。
以下先备注着,暂时归结为: 生成.so库文件 --> 运行时,需要配置链接,以便运行。
4. Compile the C Source and Create a Native Library
请注意,生成的本地库的名字,必须与 System.loadLibrary("HelloWorld");待装载库的名字相同。
Solaris:
$cc -G -I/java/include -I/java/include/solaris HelloWorld.c -o libHelloWorld.so
-G: 生成共享库
Win:
$cl -Ic:javainclude -Ic:javaincludewin32 -MD -LD HelloWorld.c
-FeHelloWorld.dll
-MD:保证与 Win32 多线程 C 库连接(译者:Win 上分静态、动态、动态多线程...C 库)
-LD: 生成动态链接库
5. Run the Program
Solaris or Win:
$java HelloWorld
输出:
Hello World!
运行前,必须保证连接器,能找到待装载的库,不然,将抛如下异常:
java.lang.UnsatisfiedLinkError: no HelloWorld in library path
at java.lang.Runtime.loadLibrary(Runtime.java)
at java.lang.System.loadLibrary(System.java)
at HelloWorld.main(HelloWorld.java)
如,Solaris, 通过 sh 或 ksh shell:
$LD_LIBRARY_PATH=.
$export LD_LIBRARY_PATH
C shell:
$setenv LD_LIBRARY_PATH .
在 Win 上,请保证待装载库在当前位置,或在 PATH 环境变量中。
你也可以如下:
java -Djava.library.path=. HelloWorld
-D:设置 Java 平台的系统属性。 此时 JavaVM 可以在当前位置找到该库。