Linux下JNI的使用方法
来源:互联网 发布:java物流管理系统源码 编辑:程序博客网 时间:2024/06/05 21:18
java是一门被广泛使用的语言,接触过大数据的都应该知道Hadoop和Spark,Hadoop就是用java编写的,虽然Spark采用的是Scala语言,其也提供对java语言的支持。有一些情况下,例如,如果我们有大量原有的经过广泛测试的非 Java 代码,将它们全部用 Java 来重写,恐怕会带来巨大的工作量和长期的测试,在比方说如果我们的应用需要访问到特定的设备,甚至是仅符合公司内部信息交互规范的设备,或某个特定的操作系统才有的特性,这时Java 就显得有些力不从心了。为了应对类似的情况,Sun 公司在 JDK1.0 中就定义了 JNI(Java native interface) 规范,它规定了 Java 应用程序对本地方法的调用规则。
另一方面,使用JNI也是有代价的。因为JAVA程序运行在JVM之上,具有平台无关的特点。但是如果Java程序通过JNI调用了原生的代码则Java程序就丧失了平台无关性。另外 JNI 调用非常耗时,一次大概要花 0.5 ~ 1 个毫秒,所以应用JNI要根据实际需求权衡利弊,做出选择。
下面通过一个简单的实例进行介绍JNI的使用方法。
(1)首先我们需要创建一个java程序。
public class HelloJni{ static{ System.loadLibrary("hello"); } public native void sayhello(); public static void main(String args[]){ HelloJni hello = new HelloJni(); hello.sayhello(); }}在这个程序中我们声明了一个本地方法sayhello()方法,并加载了名为hello的动态链接库。
(2)编译HelloJni
使用javac命令生成HellJni.class文件,这个过程会检验程序是否有语法错误。
javac HelloJni
(3)生成.h文件
使用javah命令生成HelloJni.h文件,我们要根据这个文件编写本地方法也就是hello.cpp文件,注意在hello.cpp文件中要包含这个头文件。
javah 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 __cplusplusextern "C" {#endif/* * Class: HelloJni * Method: sayhello * Signature: ()V */JNIEXPORT void JNICALL Java_HelloJni_sayhello (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif
(4)编写cpp文件
#include "HelloJni.h"#include<iostream>using namespace std;JNIEXPORT void JNICALL Java_HelloJni_sayhello (JNIEnv *, jobject){ cout << "Hello" << endl; return;}再次强调在这个文件中要包含HellJni.h这个头文件。
(5)生成动态链接库
生成动态链接库的命令另如下
g++ -fPIC -shared hello.cpp -o libhello.so -I$JAVA_HOME/include -I$JAVA_HOME/include/linux
-fPIC -shared表示生成动态链接库,如果对这个参数不了解可以参考我的linux系统下使用gcc/g++编译生成动态库这篇文章。
下面详细说一下-I参数,它表示所编译文件引入的头文件的查找目录,这里主要是指定jni.h的查找目录$JAVA_HOME/include,但是如我们所见hello.cpp文件中并没有包含这个头文件,只有HelloJni.h和iostream这两个头文件,原因是在HelloJni.h中包含了jni.h,而iostream在默认的查找目录中所以不要管。
头文件的查找顺序为-I指定,然后是系统默认的查找目录/usr/include和/usr/local/include,如果你的程序中引入的头文件不在这两个目录中,就需要特别指定。
还有一件特别重要的事是设定动态链接库的路径,否则会出现如下错误。设定动态链接库的路径的方法我在inux系统下使用gcc/g++编译生成动态库这篇文章里也有介绍,请参阅。
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello 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 HelloJni.<clinit>(HelloJni.java:10)
(6)执行java程序
在命令行输入命令java HelloJni执行java程序。
参考
https://www.ibm.com/developerworks/cn/java/l-linux-jni/
https://www.ibm.com/developerworks/cn/java/l-linux-jni/
- Linux下JNI的使用方法
- Linux下JNI的实现
- Linux下JNI的demo
- Linux下 JNI的使用
- Linux下 JNI的使用
- Linux下JNI的使用
- linux下jni的使用
- Linux下JNI的实现
- Linux下JNI的实现
- Linux下 JNI的使用
- Linux下JNI的调用
- Linux下 JNI的使用
- Linux下 JNI的使用
- Linux下 JNI的使用
- JNI的基本使用方法
- Linux下的vi使用方法
- ln linux下的使用方法
- LINUX下RPM的使用方法
- android开发:如果处理,同样的安卓应用程序在不同机器上,运行正常,但是与后台服务器交互响应时间不一样的问题?
- C语言实验——判断素数(循环结构)
- C++三大特性 -- 多态
- 【bzoj4275】[ONTAK2015]Badania naukowe
- 自定义Toast显示方法,以获取比Toast.LENGTH_SHORT还短的持续时间
- Linux下JNI的使用方法
- 十月英语
- 如何让 vim 成为我们的神器
- ls命令,alias命令及which命令
- vue引入element-ui 2.0 后报错问题解决措施
- C/C++模版
- Spring schema与命名空间(学习笔记)
- hadoop编程(8)-MapReduce案例:次排序(Secondary Sort)详解
- Android深入了解自定义属性