简介
以下试验在Ubuntu16.04 x86,jdk安装:sudo apt-get install openjdk-9-jdk-headless,原书介绍的是在win系统实现。
- 步骤
- 第一步:编写Java代码
- 第二步:编译Java代码
- 第三步:生成C语言头文件
- 第四步:编写C代码
- 第五步:生成C共享库
- 第六步:运行Java程序
- 第一步:编写Java代码
- 创建HelloJNI.java
class HelloJNI {//本地方法声明native void printHello();native void printString(String str);//加载库 以下两种方法任意一个都可以static{System.loadLibrary("hellojni");} //库名(不带lib)//static{System.load("/home/qb/work/ndk/libhellojni.so");} //绝对路径 + *.so public static void main(String args[]){HelloJNI myJNI = new HelloJNI();//调用本地方法(实际调用的是使用C语言编写的JNI本地函数)myJNI.printHello();myJNI.printString("Hello World from printString fun");} }
- 创建HelloJNI.java
- 第二步:编译Java代码
- javac HelloJNI.java
- 编译HelloJNI.java源文件
- 生成HelloJNI.class类文件
- javac HelloJNI.java
- 第三步:生成C语言头文件
若想创建本地方法的映射C函数,必须先生成函数原型,函数原型存在于C/C++头文件中,Java提供了javah工具,它位于<JDK_HOME>\bin目录下,用来生成包含函数原型的C/C++头文件,其使用方法如下。
javah <包含以native关键字声明的方法的Java类名称>
运行javah命令,会在当前目录下生成与Java类名(即javah命令的参数)相同名称的C语言头文件。在生成的C头文件中,定义了与Java本地方法相链接的C函数原型。- javah HelloJNI
1、该头文件由javah命令生成,为了保证JNI正常运行,请不要直接修改本文件的内容
2、各函数原型对应的Java代码中的本地方法,注释中标明了三个元素:类名、本地方法名、本地方法签名。只要生成了这样的函数原型,Java虚拟机就能把本地库函数与Java本地方法正常地链接在一起。
3、函数原型必须包含JNI关键字:JNIEXPORT、JNICALL,都是宏定义,定义在<JDK_HOME>/include/win32/jni_md.h
4、Java本地类型(jbyte、jint、jchar...)被定义在以下头文件中
<JDK_HOME>/include/jni.h
<JDK_HOME>/include/platform/jni_md.h - 生成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 __cplusplus extern "C" { #endif /** Class: HelloJNI* Method: printHello* Signature: ()V*/ JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *, jobject); /** Class: HelloJNI* Method: printString* Signature: (Ljava/lang/String;)V*/ JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif - JNI支持的函数命名形式:Java_类名_本地方法名
- javah HelloJNI
- 第四步:编写C/C++代码
- 创建hellojni.c
#include <jni.h> #include <stdio.h> //添加名称为env与obj的两个参数 JNIEXPORT void JNICALL Java_HelloJNI_printHello(JNIEnv *env, jobject obj) {printf("Hello World!\n");return; } JNIEXPORT void JNICALL Java_HelloJNI_printString(JNIEnv *env, jobject obj, jstring string) {//将Java String转换为C字符串const char *str = (*env)->GetStringUTFChars(env, string, 0);printf("%s!\n", str);return; }
- 创建hellojni.c
- 第五步:生成C共享库
- gcc -fpic -shared hellojni.c -o libhellojni.so -I/usr/lib/jvm/java-9-openjdk-amd64/include -I/usr/lib/jvm/java-9-openjdk-amd64/include/linux
1、可能遇到报错:
fatal error: jni.h: No such file or directory
fatal error: jni_md.h: No such file or directory
找不到jni.h和jni_md.h,只要加上-I + jni.h路径,因我的linux安装的是sudo apt-get install openjdk-9-jdk-headless,故jni.h在/usr/lib/jvm/java-9-openjdk-amd64/include;
jni_md.h在/usr/lib/jvm/java-9-openjdk-amd64/include
- gcc -fpic -shared hellojni.c -o libhellojni.so -I/usr/lib/jvm/java-9-openjdk-amd64/include -I/usr/lib/jvm/java-9-openjdk-amd64/include/linux
- 第六步:运行Java程序
- java HelloJNI
1、可能遇到报错:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hellojni in java.library.path
at java.lang.ClassLoader.loadLibrary(java.base@9-internal/ClassLoader.java:2274)
at java.lang.Runtime.loadLibrary0(java.base@9-internal/Runtime.java:874)
at java.lang.System.loadLibrary(java.base@9-internal/System.java:1807)
at HelloJNI.<clinit>(HelloJNI.java:8)
解决方法:export LD_LIBRARY_PATH=./ - 运行结果

- java HelloJNI











![linux命令详解词典pdf,[计算机]linux命令详解词典](https://img-blog.csdnimg.cn/img_convert/524d6daf746efaa52c3c71bbfe7ba172.gif)



