1.准备工作:Ubuntu安装jdk,jre
安装:
sudo apt-get install openjdk-9-jdk openjdk-9-jre
配置环境变量:
vim ~/.zshrc 添加
export JAVA_HOME=/usr/lib/jvm/java-9-openjdk-amd64
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
java调用本地c语言的库文件时,需要环境变量LD_LIBRARY_PATH.
添加环境变量:
sudo vim /etc/profile 添加
LD_LIBRARY_PATH=/home/lhg/test/jni_test/
export LD_LIBRARY_PATH
注意将/home/lhg/test/jni_test替换成自己的工程目录
2.一个JNI的例子
一个java程序例子:
HelloWorld.java
public class HelloWorld
{
public native void displayHelloWorld(); //使用native关键字修饰要调用的c函数
static
{
System.loadLibrary( "hello" ); //载入libhello.so链接库
}
public static void main( String[] args )
{
new HelloWorld().displayHelloWorld(); //调用库函数
}
}
1.要调用的c函数在java文件内只需要声明,声明时要使用native关键字修饰。
2.使用System.loadLibrary()载入c的动态共享库,上面例子中载入的动态共享库的名字为libhello.so
接下来执行如下命令,javac编译java文件,javah根据编译出来的class文件生成对应的.h文件
javac HelloWorld.java
javah HelloWorld
javah命令产生的HelloWorld.h文件内容如下:
HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
//#include <jni.h> //生成的HelloWorld.h文件是这样的,我用下面一句替换
#include "/usr/lib/jvm/java-9-openjdk-amd64/include/jni.h"
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: displayHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
上面我将程序生成的文件中include
#include "/usr/lib/jvm/java-9-openjdk-amd64/include/jni.h" //解决编译时找不到jni.h
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld( JNIEnv * j, jobject obj )
{
printf( "hello world!\n" );
return ;
}
然后使用命令生成动态库即可。
linux下生成动态共享库:
gcc -fPIC -shared -o libhello.so HelloWorld.c
输入下面命令执行即可:
java HelloWorld
后期出现的问题:
1..java文件中如果使用package语句加入包名之后,编译命令有所区别:
javac -d . HelloWorld.java
javah com.jni.HelloWorld //这里假如你的包名为com.jni