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. CF808A Lucky Year 题解

    Content 年份中有不超过 \(1\) 个非 \(0\) 数字的年份是幸运年份.现给出当前年份 \(n\),求到下一个幸运年份还要等多久. 数据范围:\(1\leqslant n\leqslant ...

  2. LuoguP7852 「EZEC-9」Yet Another Easy Problem 题解

    Content 给定 \(n,m\),你需要输出一个长度为 \(n\) 的排列,满足该排列进行不超过 \(m\) 次交换操作可以得到的最小的字典序最大. 数据范围:\(T\) 组数据,\(1\leqs ...

  3. LuoguP7043 「MCOI-03」村国 题解

    Content 有 \(T\) 组询问,每组询问给定一个有 \(n\) 个节点的数,编号为 \(1\sim n\),每个节点一开始都有权值 \(a_i\).现有 \(m\) 次操作,每次操作选择树上所 ...

  4. IDEA 修改之前保存的git地址的账号和密码

    1.打开控制面板 快捷键 win+R,然后输入control,打开控制面板 2.用户账户 3.管理windows凭据 4.点击里面的git就可以修改了

  5. python3实战之字幕vtt与字母srt的相互转换

    关于 0.本文将介绍一个字幕格式vtt与srt相互转换的py脚本. 1.代码大部分出自: https://www.cnblogs.com/BigJ/p/vtt_srt.html 2.但是自己针对上面的 ...

  6. 【LeetCode】1002. Find Common Characters 解题报告(Python)

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

  7. 基于Spring MVC + Spring + MyBatis的【图书信息管理系统(二)】

    资源下载:https://download.csdn.net/download/weixin_44893902/35123371 练习点设计:添加.删除.修改 一.语言和环境 实现语言:JAVA语言. ...

  8. MySQL测试题——开发公司人事管理系统,包括 Employee表 和 Department表

    一.需求分析 我们的开发团队,计划开发一款公司人事管理软件,用于帮助中小型企业进行更加高效的人事管理.现在需要对数据库部分进行设计和开发,根据对需求和立项的分析,我们确定该数据库中最核心的两个表为员工 ...

  9. 编写Java程序,实现多线程操作同一个实例变量的操作会引发多线程并发的安全问题。

    查看本章节 查看作业目录 需求说明: 多线程操作同一个实例变量的操作会引发多线程并发的安全问题.现有 3 个线程代表 3 只猴子,对类中的一个整型变量 count(代表花的总数,共 20 朵花)进行操 ...

  10. 如何下载安装JDBC_jar包,MySQL_JDBC_jar包的下载与使用(Windows)

    一. 下载 (1) 打开MySQL_JDBC的下载网站:https://dev.mysql.com/downloads/connector/j/ (2) 选择操作系统:Platform Indepen ...