简析java JNI技术

前言

   认识JNI(Java Native Interface)技术,了解Java调用本地C/C++库的简单原理以及一些基本的知识点;自己编写一个自定义的JNI接口。

一、简介        

   JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

        本地代码与 Java 虚拟机之间是通过 JNI 函数实现相互操作的。JNI 函数通过接口指针来获得,本地方法将 JNI 接口指针当作参数来接受。虚拟机保证在从相同的 Java 线程中对本地方法进行多次调用时,传递给本地方法的接口指针是相同的,本地方法被不同的 Java 线程调用时,它接受不同的 JNI接口指针。

        JNI的强大特性使我们在使用JAVA平台的同时,还可以重用原来的本地代码。作为虚拟机实现的一部分,JNI允许JAVA和本地代码间的双向交互。

1、什么是java jni

        JNI是Java Native Interface的缩写,通过使用 Java本地接口书写程序,可以确保代码在不同的平台上方便移植。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。

        本地代码与 Java 虚拟机之间是通过 JNI 函数实现相互操作的。JNI 函数通过接口指针来获得,本地方法将 JNI 接口指针当作参数来接受。虚拟机保证在从相同的 Java 线程中对本地方法进行多次调用时,传递给本地方法的接口指针是相同的,本地方法被不同的 Java 线程调用时,它接受不同的 JNI接口指针。

        JNI的强大特性使我们在使用JAVA平台的同时,还可以重用原来的本地代码。作为虚拟机实现的一部分,JNI允许JAVA和本地代码间的双向交互。

2、jni 的应用场景

 2.1 解决性能问题

    在程序对时间敏感或对性能要求特别高时,有必要使用更底层的语言,例如使用C或者C++来实现具体功能,然后在java中直接调用这些功能。

2.2、 解决本机平台接口调用问题

     JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。

2.3、嵌入式开发应用

       “一次编程,到处使用”的Java软件概念原本就是针对网上嵌入式小设备提出的,几经周折,目前SUN公司已推出了J2ME(Java 2 P1atform Micro Edition)针对信息家电的Java版本,其技术日趋成熟,开始投入使用。SUN公司Java虚拟机(JVM)技术的有序开放,使得Java软件真正实现跨平台运行,即Java应用小程序能够在带有JVM的任何硬软件系统上执行。加上Java语言本身所具有的安全性、可靠性和可移植性等特点,对实现瘦身上网的信息家电等网络设备十分有利,同时对嵌入式设备特别是上网设备软件编程技术产生了很大的影响。也正是由于JNI解决了本机平台接口调用问题,于是JNI在嵌入式开发领域也是如火如荼。

3、Java 和JNI基本类型对照及基本实现

      java的基本类型可以直接与C/C++的基本类型映射。

Java与JNI引用类型对照表:

4、简单的实现案例

  4.1、 在java类中申明Native方法(此类为JNI类程序,担任代理角色),并编译成class文件(在此类中同时也需要加载需要使用的类库)

public class MainActivity {
    static {
        //这种方式需要把MainActivity.dll放在jdk/bin目录下
        System.loadLibrary("MainActivity");
        //System.load("C:\\Users\\Administrator.DESKTOP-Q7DQAHS\\source\\repos\\ProjectNewDll\\x64\\Debug\\ProjectNewDll.dll");
    }

    public static native String stringFromJNI();

    public static void main(String[] args) {
        System.out.println("exec " + stringFromJNI());
    }
}

    这里声明了一个native方法stringFromJNI(),并指定实现此接口的动态库名称为MainActivity.dll,存放在jdk/bin目录下。

  4.2、 用javah将第一步的class文件生成头文件(具体命令:javah -jni XXX, javah程序统一了java中的native方法、头文件中的函数名和动态库中的函数实现之间的对应关系)

     javac MainActivity :生成字节码文件

    javah -classpath  absolutepath\src\main\java  com.game.test.jni.MainActivity :生成可用的头文件com_game_test_jni_MainActivity.h,内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_game_test_jni_MainActivity */

#ifndef _Included_com_game_test_jni_MainActivity
#define _Included_com_game_test_jni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_game_test_jni_MainActivity
 * Method:    stringFromJNI
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_game_test_jni_MainActivity_stringFromJNI
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

 

  4.3、 用其他语言(C、C++等)实现上述头文件中的函数,生成动态库,供java程序使用

    关于动态库的编写,参照网上他人的实现:visual studio编写jni踩坑 - 简书,不在复述。

  4.4、 发布java和动态库

   把生成的MainActivity.dll动态库放在jdk/bin目录下,执行MainActivity → main() 就能看到输出结果了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/23591.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux命令(22)之chage

Linux命令之chage 1.chage介绍 chage命令用来更改linux用户密码到期信息&#xff0c;包括密码修改间隔最短、最长日期、密码失效时间等等。 2.chage用法 chage [参数] 用户名 chage常用参数 参数说明-m密码可更改的最小天数&#xff0c;为0表示可以随时更改-M密码有效期最大…

神经网络语言模型(NNLM)

神经网络语言模型【NNLM】 1 为什么使用神经网络模型&#xff1f;2 什么是神经网络模型&#xff1f;3. 代码实现3.1 语料库预处理代码3.2 词向量创建3.3 NNLM模型类3.4 完整代码 1 为什么使用神经网络模型&#xff1f; 解决独热编码无法解决词之间相似性问题 使用神经网络语言…

Blazor实战——Known框架增删改查导

本章介绍学习增、删、改、查、导功能如何实现&#xff0c;下面以商品资料作为示例&#xff0c;该业务栏位如下&#xff1a; 类型、编码、名称、规格、单位、库存下限、库存上限、备注 1. 前后端共用 1.1. 创建实体类 在KIMS项目Entities文件夹下创建KmGoods实体类该类继承Ent…

【C++】类和对象的应用案例 2 - 点和圆的关系

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01;时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、分析 3、示例代码 1 4、代码优化 4.1、point.h 4.2、point.c 4.3、circle.h 4.4、circle.c 4.4、main.c …

Netty 源码分析系列(十八)一行简单的writeAndFlush都做了哪些事?

文章目录 前言源码分析ctx.writeAndFlush 的逻辑writeAndFlush 源码ChannelOutBoundBuff 类addMessage 方法addFlush 方法AbstractNioByteChannel 类 小结 前言 对于使用netty的小伙伴来说&#xff0c;我们想通过服务端往客户端发送数据&#xff0c;通常我们会调用ctx.writeAn…

实时聊天组合功能,你了解吗?

你有兴趣安装实时聊天组合功能吗&#xff1f;如果您选择了SaleSmartly&#xff08;ss客服&#xff09;&#xff0c;您的实时聊天插件可以不仅仅只是聊天通道&#xff0c;还可以有各种各样的功能&#xff0c;你不需要包含每一个功能&#xff0c;正所谓「宁缺勿滥」&#xff0c;功…

再获认可!腾讯连续三年被Gartner列为CWPP供应商之一

随着云的快速发展&#xff0c;企业的工作负载已经从服务器发展到虚拟机、容器、serverless等&#xff0c;部署的模式也日益复杂&#xff0c;包括公有云、混合云和多云等。在此背景下&#xff0c;传统的主机安全防护已无法满足需求&#xff0c;CWPP&#xff08;云工作负载保护平…

C#,码海拾贝(23)——求解“复系数线性方程组“的“全选主元高斯消去法“之C#源代码,《C#数值计算算法编程》源代码升级改进版

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static partial class LEquations { /// <summary&g…

day20 - 绘制物体的运动轨迹

在我们平常做目标检测或者目标追踪时&#xff0c;经常要画出目标的轨迹图。绘制轨迹图的一种方法就是利用光流估计来进行绘制。 本期我们主要来介绍视频中光流估计的使用和效果&#xff0c;利用光流估计来绘制运动轨迹。 完成本期内容&#xff0c;你可以&#xff1a; 掌握视…

网站部署与上线(1)虚拟机

文章目录 .1 虚拟机简介2 虚拟机的安装 本章将搭建实例的生产环境&#xff0c;将所有的代码搭建在一台Linux服务器中&#xff0c;并且测试其能否正常运行。 使用远程服务器进行连接&#xff1b; 基本的Linux命令&#xff1b; 使用Nginx搭建Node.js服务器&#xff1b; 在服务器端…

一、预约挂号详情

文章目录 一、预约挂号详情1、需求分析 2、api接口2.1 添加service接口2.2 添加service接口实现2.2.1 在ScheduleServiceImpl类实现接口2.2.2 在获取科室信息 2.3 添加controller方法 3、前端3.1封装api请求3.2 页面展示 二、预约确认1、api接口1.1 添加service接口1.2 添加con…

通过python采集整站lazada商品列表数据,支持多站点

要采集整站lazada商品列表数据&#xff0c;需要先了解lazada网站的结构和数据源。Lazada是东南亚最大的电商平台之一&#xff0c;提供各种商品和服务。Lazada的数据源主要分为两种&#xff1a;HTML和API。 方法1&#xff1a;采集HTML数据 步骤1&#xff1a;确定采集目标 首先…

一、CNNs网络架构-基础网络架构(LeNet、AlexNet、ZFNet)

目录 1.LeNet 2.AlexNet 2.1 激活函数&#xff1a;ReLU 2.2 随机失活&#xff1a;Droupout 2.3 数据扩充&#xff1a;Data augmentation 2.4 局部响应归一化&#xff1a;LRN 2.5 多GPU训练 2.6 论文 3.ZFNet 3.1 网络架构 3.2 反卷积 3.3 卷积可视化 3.4 ZFNet改…

Java的Arrays类的sort()方法(41)

目录 sort&#xff08;&#xff09;方法 1.sort&#xff08;&#xff09;方法的格式 2.使用sort&#xff08;&#xff09;方法时要导入的类 3.作用 4.作用的对象 5.注意 6.代码及结果 &#xff08;1&#xff09;代码 &#xff08;2&#xff09;结果 sort&#xff08;&…

【Netty】字节缓冲区 ByteBuf (六)(上)

文章目录 前言一、ByteBuf类二、ByteBuffer 实现原理2.1 ByteBuffer 写入模式2.2 ByteBuffer 读取模式2.3 ByteBuffer 写入模式切换为读取模式2.4 clear() 与 compact() 方法2.5 ByteBuffer 使用案例 总结 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&…

亏损?盈利?禾赛科技Q1财报背后的激光雷达赛道「现实」

随着禾赛科技在去年登陆美股&#xff0c;作为全球为数不多已经开始前装量产交付的激光雷达上市公司&#xff0c;财务数据的变化&#xff0c;也在一定程度上反映了行业的真实状况。 根据禾赛科技最新发布的今年一季度财报显示&#xff0c;公司季度净营收为4.3亿元&#xff08;人…

day13 - 对指纹图片进行噪声消除

在指纹识别的过程中&#xff0c;指纹图片通常都是现场采集的&#xff0c;受环境的影响会有产生很多的噪声点&#xff0c;如果直接使用&#xff0c;会对指纹的识别产生很大的影响&#xff0c;而指纹识别的应用场景又都是一些比较严肃不容有错的场合&#xff0c;所以去除噪声又不…

python+vue空巢老人网上药店购药系统9h2k5

本空巢老人购药系统主要包括三大功能模块&#xff0c;即用户功能模块、家属功能模块和管理员功能模块。 &#xff08;1&#xff09;管理员模块&#xff1a;系统中的核心用户是管理员&#xff0c;管理员登录后&#xff0c;通过管理员功能来管理后台系统。主要功能有&#xff1a;…

【实验】SegViT: Semantic Segmentation with Plain Vision Transformers

想要借鉴SegViT官方模型源码部署到本地自己代码文件中 1. 环境配置 官网要求安装mmcv-full1.4.4和mmsegmentation0.24.0 在这之前记得把mmcv和mmsegmentation原来版本卸载 pip uninstall mmcv pip uninstall mmcv-full pip uninstall mmsegmentation安装mmcv 其中&#xff…

旋翼无人机常用仿真工具

四旋翼常用仿真工具 rviz&#xff1a; 简单的质点&#xff08;也可以加上动力学姿态&#xff09;&#xff0c;用urdf模型在rviz中显示无人机和飞行轨迹、地图等。配合ROS代码使用&#xff0c;轻量化适合多机。典型的比如浙大ego-planner的仿真&#xff1a; https://github.c…