您的位置:首页 > 运维架构 > Linux

Linux 平台下JNI的使用

2017-03-26 21:10 337 查看
本文简单介绍下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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: