Linux下JNI的使用方法

         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 __cplusplus
extern "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/




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了在Linux环境下使用GmSSL的JNI接口,需要按照以下步骤进行操作: 1. 首先,在Linux系统上编译和安装GmSSL。可以从gmssl.git仓库中获取源代码,并执行make命令进行编译,然后使用make install命令将GmSSL安装到指定路径。比如,可以使用以下命令指定安装路径为`/usr/local/gmssl`: ``` make make install PREFIX=/usr/local/gmssl ``` 2. 编译成功后,可以在安装路径下找到生成的gmssl目录。接下来,需要将可执行文件gmssl复制到gmssl/bin目录,并生成JNI所需的动态链接库。具体的操作可以参考以下步骤: ``` cp gmssl /usr/local/gmssl/bin cd /usr/local/gmssl ldconfig # 更新动态链接库的缓存 ``` 3. 在使用JNI接口时,可以在应用程序中引入GmSSL的头文件,并调用相关的函数。例如,在GmSSL.c中可以实现描述中的简易JNI接口,同时也可以进行简单封装,方便直接调用sm2、sm3、sm4等算法。 总结起来,要在Linux环境下使用GmSSL的JNI接口,需要先编译和安装GmSSL,然后将可执行文件复制到指定目录,并生成JNI所需的动态链接库。最后,在应用程序中引入头文件并调用相关函数即可。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [GmSSL win10编译安装](https://blog.csdn.net/liuxing9345/article/details/110742166)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [java版sm4源码-gmssl-java-sdk:gmssl-java-sdk](https://download.csdn.net/download/weixin_38530995/19393365)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值