1.JNI是什么?

JNI(Java Native Interface) Java本地接口,又叫Java原生接口。它允许Java调用C/C++的代码,同时也允许在C/C++中调用Java的代码。

可以把JNI理解为一个桥梁,连接Java和底层。其实根据字面意思,JNI就是一个介于Java层和Native层的接口,而Native层就是C/C++层面。

2.为什么要用JNI?

  1. 能够重复使用一些现成的、具有相同功能的的C/C++代码
  2. 因为C/C++是偏向底层的语言,所以使用C/C++能够更加的高效,而且也使得Java能够访问操作系统中一些底层的特性。

3.怎么使用JNI?

完整的示例源码托管在 Github

  1. 使用Java声明native方法
// com/maxzuo/jni/StringUtils.java
public class StringUtils { public static native String getRandStr(int length);
}
  1. 使用javac编译StringUtils.java成StringUtils.class
// 在src/main/java目录下执行
javac com/maxzuo/jni/StringUtils.java
  1. 使用上面生成的class文件生成头文件用于编写C/C++代码的头文件:
// 在src/main/java目录下执行
javah -jni com.maxzuo.jni.StringUtils // 执行完命令后,生成了com_maxzuo_jni_StringUtils.h文件
  1. 用C语言来实现函数
#include "com_maxzuo_jni_StringUtils.h"

JNIEXPORT jstring JNICALL Java_com_maxzuo_jni_StringUtils_getRandStr(JNIEnv *env,jobject obj, int length){
...
}

其中:

将java的native方法转换成C函数声明的规则是这样的:Java_{package_and_classname}_{function_name}(JNI arguments),包名中的点换成单下划线。

参数介绍:

  • JNIEnv *:这是一个指向JNI运行环境的指针,后面我们会看到,我们通过这个指针访问JNI函数
  • jobject:这里指代java中的this对象
  1. 生成动态库文件
// 将生成的头文件放在native目录, 在native目录下执行如下命令:
gcc -dynamiclib -I /Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/include -I /Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home/include/darwin StringUtils.c -o libStringUtils.jnilib

注意在不同的操作系统,能够生成的动态库文件也是不一样的,在Windows中,要生成.dll文件,在Linux中要生成.so文件,在Mac OS X中要生成.jnilib文件。

同时定义生成的库文件名的时候也要遵循:lib+文件名+扩展名的原则。本例中我们在Mac OS X中所以我们定义生成的库文件为:libStringUtils.jnilib。

  1. 使用生成的动态库文件
// com/maxzuo/jni/Main.java
public class Main { static {
System.load("/xxx/java-native-interface/native/libStringUtils.jnilib");
} public static void main(String[] args) {
String randStr = StringUtils.getRandStr(4);
System.out.println("call StringUtils.getRandStr str = " + randStr);
}
}

其中,运行时加载本地库, JDK提供了两个方法:

  • System.loadLibrary(String libname) 加载由libname参数指定的系统,参数为库文件名,不包含库文件的扩展名;会自动加载依赖。

    譬如libA.so和libB.so有依赖关系,虚拟机在载入libA.so的时候会先去java.library.path下查找libB.so。

  • System.load(String filename):参数为库文件的绝对路径且带文件后缀;不会自动加载依赖。同等场景下,不会自动加载依赖。

补充:

1)通过JVM启动参数指定:-Djava.library.path=/path

2)通过设置环境变量指定:export LD_LIBRARY_PATH=/path

Java基础-JNI入门示例的更多相关文章

  1. Java基础语法入门01

    Java基础语法入门01 学习java你要先进行去了解JDK,JRE,JVM JDK Java开发工具包 JRE Java语言开发的运行环境 JVM Java虚拟机,用于Java语言的跨平台所用. 当 ...

  2. java基础知识入门

    一.java简介及原理图 Java的前世今生 Java之父詹姆斯·高斯林: 1967年, 12岁用报废的电话机和电视做了一台电子游戏机; 1983年, 获得卡内基梅隆大学计算机科学博士学位; 1983 ...

  3. Java基础之入门

    写写基础,顺便回顾下,再深层次思考下哪些深入的没弄明白. Java是Sun Microsystems于1995年推出的高级编程语言  其版本 由 1.1 -> 1.2 -> 1.3 -&g ...

  4. Java基础之入门介绍

    基础知识 1.JVM.JRE和JDK的区别:     JVM(Java Virtual Machine):java虚拟机,用于保证java的跨平台的特性.                   java ...

  5. Java基础(入门Java)

    今天是学习Java的第一天,为了保证在暑假里持续高效的学习,决定每周写一篇博客汇报总结当周进度,以此来督促自己不断的向更深更远的方向迈进.Java刚刚入门,看到的人若觉得某些地方不妥欢迎进行批评指导, ...

  6. 二十二、Java基础--------GUI入门

    在java学习过程中GUI是一个比较特殊的知识体系(笔者对安卓不是很了解),似乎在为安卓的学习做着准备,本文将将展示一个综合案例. 创建一个类似于记事本的程序,包含打开与保存功能. package G ...

  7. Java基础语法入门

    一.Java运行原理 写好java代码,执行javac命令,通过jvm把.java源文件编译成.class文件,执行java命令把字节码文件编译成特定平台能识别的机器码 二.标识符 1.标识符是用于数 ...

  8. [java 基础]反射入门

    原文 概况 使用java的反射,可以让我们检查(或者修改)类,接口,字段,方法的特性.当你在编译期不知道他们的名字的时候非常有用. 除此之外,可以使用反射来创建实例,调用方法或者get/set 字段值 ...

  9. Java基础 while 简单示例

        JDK :OpenJDK-11      OS :CentOS 7.6.1810      IDE :Eclipse 2019‑03 typesetting :Markdown   code ...

随机推荐

  1. CF1090M The Pleasant Walk 题解

    Content 有一个长度为 \(n\) 的数组 \(a_1,a_2,a_3,...,a_n\),并已知有 \(k\) 个不相同的元素求最长连续的一段区间,使得这里面的元素互不相同. 数据范围:\(1 ...

  2. SP16033 TIPTOP - Tip Top Game 题解

    Description Alim 和 Sufian 是好朋友.他们最近找到了一个好玩的游戏,叫做 Tip Top.游戏规则如下: 确定一个整数. 找出这个整数的所有因子. Alim 先手,每人轮流取一 ...

  3. CF289B Polo the Penguin and Matrix 题解

    Content 有一个 \(n\times m\) 的矩阵 \(A\),每次操作你可以将某一个元素增加或减少 \(d\),求是所有元素相等的最小操作次数,或者不存在这样的操作方案. 数据范围:\(1\ ...

  4. 开发webpart时建立图像文件夹和CSS,js文件夹

    如图所示:是通过添加映射来完成,做好之后,把图像拷到文件夹时,当ascx文件里需要用到图像时,直接把图像拖到ascx文件里的位置.这样就知道该图像的路径 了.

  5. python dumps和loads

    dumps和loads的使用 import json dict = {'姓名': 'supermao','年龄': '19','爱好': '未知', '地区': '武汉'} string=json.d ...

  6. 10分钟uniapp实现即时通讯,腾讯云IM的正确打开方式get

    官方的demo基本上覆盖了所有功能点 今天在使用uniapp开发即时通讯IM的时候遇到了瓶颈,便在uniapp的插件市场搜寻一波看看有没有成熟的轮子借鉴,终于发现了这个宝藏插件--"智密 - ...

  7. 【PS算法理论探讨二】 Photoshop中图层样式之 投影样式 算法原理初探讨。

    接下来几篇文章我们将稍微简单的探索下PS中多种图层混合模式的算法内部原理,因为毕竟没有这方面的官方资料,所以很多方面也只是本人自己的探索和实践,有可能和实际的情况有着较大的差异. 在PS的实践中,图层 ...

  8. 辅助函数和高阶函数 map、filter、reduce

    辅助函数和高阶函数 map.filter.reduce: 一.辅助函数:(1-1)响应式函数 (数组更新检测):    push()    pop()    shift()    unshift()  ...

  9. 【LeetCode】621. Task Scheduler 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 公式法 日期 题目地址:https://leetco ...

  10. 【LeetCode】92. Reverse Linked List II 解题报告(Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 迭代 递归 日期 题目地址:https://leet ...