本文简单介绍下Linux平台下JNI开发环境的搭建
声明一个native方法
public static native void helloJni();
使用javah 工具生成C/C++ .h文件
先 cd到当前的src目录下
然后
# tianrui.JniTest 是这个类的包名
/src$ javah -classpath . -jni tianrui.JniTest
javah 调用完成后, 会生成一个tianrui_JniTest.h
文件, 其实就是包名_类名.h
文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class tianrui_JniTest */
#ifndef _Included_tianrui_JniTest
#define _Included_tianrui_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: tianrui_JniTest
* Method: helloJni
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_tianrui_JniTest_helloJni
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
中间这个方法就是我们需要在native层实现的方法, 写一个C/C++引入这个.h文件即可
C/C++完成方法内容
#include <stdio.h>
#include <jni.h>
#include "tianrui_JniTest.h"
/*
* Class: tianrui_JniTest
* Method: helloJni
* Signature: ()V
*/
/*记得手动把形参变量名补上, .h文件中系统没有帮我们生成*/
JNIEXPORT void JNICALL Java_tianrui_JniTest_helloJni(JNIEnv * env, jclass obj)
{
/*只是简单的输出Hello Jni...*/
printf("Hello Jni...");
return;
}
使用gcc编译成.o文件
假设已经装了gcc, 下面开始编译
# -----/opt/java-oracle-1.8/jdk1.8.0_91/include 是jni.h目录
# -----/opt/java-oracle-1.8/jdk1.8.0_91/include/linux 是jni_md.h目录
# 少了这两个目录将不能编译
gcc -fPIC -D_REENTRANT -I/opt/java-oracle-1.8/jdk1.8.0_91/include -I/opt/java-oracle-1.8/jdk1.8.0_91/include/linux -c tianrui_JniTest.c
使用gcc进行链接,将.o文件生成libXXX.so文件
Note: 和windows下不同,linux的库文件必须是以libxxx.so形式命令的(或者 libxxx.so.y,y是版本号),lib前缀是为了系统能够识别它,xxx是java代码System.loadLibrary(“xxx”);中引用库的名字。
# 在当前目录下会生成.so文件,我们在类中进行加载这个so文件就可以了
gcc -shared tianrui_JniTest.o -o libtianrui.so
使用System.load(“so路径”)或System.loadLibrary(” LD_LIBRARY_PATH 下的libXXX.so”) 进行加载
使用loadLibrary时需要配置LD_LIBRARY_PATH
环境变量, linux下直接export就可以
# 导入环境变量
export LD_LIBRARY_PATH=/home/user/lib
完整代码
package tianrui;
/**
* Created by yangtianrui on 17-3-21.
* <p>
* 1. 使用javah生成 包名_类名.h文件
* /src$ javah -classpath . -jni tianrui.JniTest
*
* 2. 完善 包名_类名.c 文件(代码逻辑)
*
* 3. 使用gcc进行编译成 .o文件
* gcc -fPIC -D_REENTRANT -I/opt/java-oracle-1.8/jdk1.8.0_91/include -I/opt/java-oracle-1.8/jdk1.8.0_91/include/linux -c tianrui_JniTest.c
* -----/opt/java-oracle-1.8/jdk1.8.0_91/include 是jni.h目录
* -----/opt/java-oracle-1.8/jdk1.8.0_91/include/linux 是jni_md.h目录
* 少了这两个目录不能编译
*
* 4. 使用gcc进行链接,将.o文件生成libXXX.so文件
* gcc -shared tianrui_JniTest.o -o libtianrui.so
*
* 5. 使用System.load("so路径"), 或者使用System.loadLibrary("XXX");加载. LD_LIBRARY_PATH 下的libXXX.so
*
*/
public class JniTest {
static {
// 无需放在 LD_LIBRARY_PATH 目录下
// System.load("/home/yangtianrui/IdeaProjects/okhttp_debug/src/jni/tianrui.so");
System.loadLibrary("tianrui");
}
public static void main(String[] args) {
helloJni();
}
public static native void helloJni();
}