Overview
准备过程:
-
创建一个类(HelloWorld.java)
-
使用javac编译该类
-
利用javah -jni产生头文件
-
用本地代码实现头文件中定义的方法
- Run
具体流程如下图所示
接下来,详细介绍每个步骤的代码以及操作
1.HelloWorld.java
class HelloWorld {
private native void print();
public static void main(String[] args) {
new HelloWorld().print();
new Thread().start();
}
static {
System.loadLibrary("HelloWorld");
}
}
2.
使用javac编译该类
$javac HelloWorld.java
生成HelloWorld.class文件
3.利用javah -jni产生头文件
命令如下:javah -jni 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
4.
用本地代码实现头文件中定义的方法
自己创建一个HelloWorld.c文件,基于上面生成的HelloWorld.h文件
#include "jni.h"
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
5.使用命令生成.so文件(注意,如果是windows环境是生成.dll文件,linux下是.so文件)
命令如下:(注意这里的so文件命令格式,lib+前面代码中System.loadLibrary(“HelloWorld”)的HelloWorld.so)
gcc HelloWorld.c -I "/usr/lib/LOCALCLUSTER/jdk1.8.0_162/include" -I "/usr/lib/LOCALCLUSTER/jdk1.8.0_162/include/linux" -fpic -shared -o libHelloWorld.so
注意:这里如果不加上include的路径,可能会出现下面的错误:
HelloWorld.c:1:17: fatal error: jni.h: No such file or directory
#include "jni.h"
^
compilation terminated.
这样正确生成.so文件后,尝试直接使用命令
java HelloWorld
会看到下面的错误信息:
[root@hdh133 JNI]# java HelloWorld
Exception in thread "main" java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at HelloWorld.<clinit>(HelloWorld.java:9)
这个时候,需要进行这一步操作:
export LD_LIBRARY_PATH=.
然后再次执行java HelloWorld,看到运行结果为
参考链接:
https://stackoverflow.com/questions/13466777/jni-h-no-such-file-or-directory