如何快速使用JNI
文章目录
- 1_JNI是什么?
- 2_使用
- 3_扩展
1_JNI是什么?
JNI 是Java Native Interface的缩写,通过JNI,允许Java代码与其他语言(通常是C或C++)编写的本地应用程序或库进行交互。简而言之就是,Java可以通过JNI调用C 或 C++ 语言写的代码。
2_使用
1、首先,准备一个demo让我们进行JNI的快速入门使用:
/*** @author shenyang* @version 1.0* @info JNI* @since 2024/6/29 下午5:03*/
public class JNIDemo {public static void main(String[] args) {System.out.println(System.getProperty("java.library.path"));System.out.println(add(1,2));}
}
2、需要将C/C++实现的方法用native关键字声明。
- 由
native关键字声明的方法我们就不需要给出方法体了,直接给出声明就好了。
public static native int add(int a, int b);//这个方法的作用是将两个整型相加
3、加载动态链接库(windows上.dll为后缀,linux上.so为后缀名),通常是使用静态代码块来进行导入。
- 使用 System对象的
public static void loadLibrary(String libname)方法不需要后缀,只要(库所在路径加上)库名。
static {System.loadLibrary("jniDemo");
}
4、使用 javac -h或 javah生成.h为后缀的头文件
- 注意:jdk10之后将
javah这一命令移除了,JEP313: 移除JDK中附带的javah工具。 - 注意下面第一个参数是存放到当前路径下(
./)
javac -h ./ JNIDemo.java
- 生成的头文件
JNIDemo.h。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h> //这个头文件在jdk/include/下
/* Header for class JNIDemo */#ifndef _Included_JNIDemo
#define _Included_JNIDemo
#ifdef __cplusplus
extern "C" {
#endif
/** Class: JNIDemo 说明这个方法是在哪个类里* Method: add 对应的是java中的add方法* Signature: (II)I 括号里两个II表示第一个参数和第二个参数都是int类型,括号后面的I表示这个方法的返回值是int类型* 下面这部分是C++需要实现的函数声明*/
JNIEXPORT jint JNICALL Java_JNIDemo_add(JNIEnv *, jclass, jint, jint);#ifdef __cplusplus
}
#endif
#endif
下面这部分是C++需要实现的函数声明:
JNIEXPORT jint JNICALL Java_JNIDemo_add(JNIEnv *, jclass, jint, jint);
5、根据生成的头文件里的函数声明实现对应的函数,创建JNIDemo.cpp文件。
- 注意:下面的代码包含了之前生成的头文件
JNIDemo.h,还需要其他头文件也可以一并包含进去,比如:iostream。 - 下面四个参数:
JNIEnv *是一个指针封装了一些JNI的操作在里面,jclass参数也用不到只放一个参数类型就行了,后面两个参数因为用的到所以把参数名加上。 - 函数的最终目的是返回
a+b,再加上一些其他操作我们进行测试;
#include "JNIDemo.h"
#include <iostream>JNIEXPORT jint JNICALL Java_JNIDemo_add(JNIEnv *, jclass , jint a, jint b)
{std::cout <<"a = "<< a<<" b= "<< b <<std::endl;return a+b;
}
6、将上面的cpp文件编译成动态链接库。
给对C++不太了解的同学解释下下面命令的意义:
-
-o jniDemo.dll: 指定输出文件的名称为jniDemo.dll(与System.loadLibrary("jniDemo")中保持统一)。在Windows系统上,动态链接库通常以.dll为扩展名。 -
-fPIC: 表示生成位置无关代码(Position-Independent Code)。这是生成共享库时常用的选项,使得生成的代码在加载到内存中的任何位置时都可以正确运行。 -
-shared: 指定生成一个共享库(动态链接库),而不是可执行文件。 -
-I: 包含路径选项,用于指定头文件所在目录。在这里,包含了特定于Windows系统的Java头文件。 -
JNIDemo.cpp: 源文件名,包含了具体的JNI方法实现。 -
如果
windows电脑上使用不了g++命令,那么可以下载MinGWX64 - x86_64-win32-sjlj。
g++ -o jniDemo.dll -fPIC -shared -I"E:\shenyang\.jdks\jdk-1.8\include\win32" -I"E:\shenyang\.jdks\jdk-1.8\include" JNIDemo.cpp
执行完毕后发先目录下出现jniDemo.dll文件:

最后运行 JNIDemo.java ,查看运行结果:

3_扩展
基础数据类型对应表:
| Java 类型 | JNI 类型 | C/C++ 类型 | 描述 |
|---|---|---|---|
boolean | jboolean | unsigned char | 布尔类型,值为true或false ,使用0表示false,非0表示true。 |
byte | jbyte | signed char | 8位有符号整数 |
char | jchar | unsigned short | 16位无符号Unicode字符 |
short | jshort | short | 16位有符号整数 |
int | jint | int | 32位有符号整数 |
long | jlong | long long | 64位有符号整数 |
float | jfloat | float | 32位单精度浮点数 |
double | jdouble | double | 64位双精度浮点数 |
void | void | void | 无类型 |
引用数据类型对应表:
| Java 类型 | JNI 类型 | 描述 |
|---|---|---|
String | jstring | Java字符串 |
Object | jobject | 任意Java对象 |
Class | jclass | Java类 |
Throwable | jthrowable | Java异常对象 |
boolean[] | jbooleanArray | 布尔型数组 |
byte[] | jbyteArray | 字节型数组 |
char[] | jcharArray | 字符型数组 |
short[] | jshortArray | 短整型数组 |
int[] | jintArray | 整型数组 |
long[] | jlongArray | 长整型数组 |
float[] | jfloatArray | 单精度浮点型数组 |
double[] | jdoubleArray | 双精度浮点型数组 |
| 任意类型的对象数组 | jobjectArray | 对象数组 |
| Java数组中的任意类型 | jarray | 通用数组类型 |
相关文章:
如何快速使用JNI
文章目录 1_JNI是什么?2_使用3_扩展 1_JNI是什么? JNI 是Java Native Interface的缩写,通过JNI,允许Java代码与其他语言(通常是C或C)编写的本地应用程序或库进行交互。简而言之就是,Java可以通…...
simulink开发stm32,使用中断模块,无法产生中断,其中包括使用timer模块,以及ADC都无法产生中断,需要注意的地方
1,其中包括使用timer模块,以及ADC都无法产生中断,需要注意的地方 原来是需要在配置文件里开启一下timer的中断,其他模块自动加载ioc就可以了,这个timer需要注意力,需要自己勾选一下 如下图: 看…...
C# 如何单纯的优化循环
Parallel.For(0, 10000, i >{// 并行执行的代码块// 例如: Console.WriteLine(i);}); 这种循环比 单纯常用的for 和 foreach 要稍微快一点 但是呢如果循环里面写的是非常简单的业务逻辑 的话 for和foreach 要更胜一筹一点 Parallel 原理就好像我一个人忙不过来可以多找几个…...
【鸿蒙学习笔记】@Extend装饰器:定义扩展组件样式
官方文档:Extend装饰器:定义扩展组件样式 [Q&A] Extend装饰器 作用 Extend用于扩展原生组件样式。 [Q&A] Extend装饰器 特点 1・Extend仅支持在全局定义,不支持在组件内部定义。 2・Extend支持封装指定组件的…...
【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF
【Docker项目实战篇】Docker部署PDF多功能工具Stirling-PDF 前言一、Stirling-PDF介绍1.1 Stirling-PDF简介1.2 Stirling-PDF功能 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四…...
【算法训练记录——Day37】
Day37——贪心Ⅴ 1.leetcode_56合并区间 1.leetcode_56合并区间 思路:排序,如果重叠,更新right 为max(right, curVal), 不重叠就加入res,需要单独考虑最后一次,因为每次都是在下一次遍历开始时判断是否加入res,因此 当…...
OpenCV 张正友标定法(二)
文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 在之前的博客OpenCV 张氏标定法中,我们没有考虑镜头畸变等因素,因此计算出的内参与外参均是理想情况下的数值,而如果我们考虑到镜头的畸变: 我们就需要考虑使用最小二乘法最小化像素坐标的重投影误差(上述所求…...
LeetCode题练习与总结:环形链表Ⅱ--142
一、题目描述 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测…...
【kaptcha】kaptcha验证码的使用-SpringBoot集成
Kaptcha验证码的依赖 <dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version> </dependency> Kaptcha验证码的配置类,对验证码的一些属性进行配置&#x…...
golang template模板嵌套语法 为何不能使用变量 底层源码解析
我们都知道在golang的模板语法中,我们可以使用template关键字嵌套其他模块, 如: {{template "模板文件名" .}} 然而,这里的 “模板文件名” 是不能使用变量的! 注意这里最后的的 . 这个实际上是templa…...
【Linux】线程Thread
🔥博客主页: 我要成为C领域大神🎥系列专栏:【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 线程概述 …...
RAG技术:在自然语言处理中的深度融合与创新
在自然语言处理(NLP)领域,随着技术的不断进步,我们见证了各种创新方法的涌现。其中,检索增强生成(Retrieval-Augmented Generation,简称RAG)技术以其独特的优势,逐渐成为…...
什么是std::bind
2024年6月29日,周日下午 std::bind 是一个C11标准库中的函数,它用于将一个函数或函数对象与特定的参数绑定在一起,生成一个新的函数对象。 std::bind通常和std::function一起使用,因为std::function可以作为一个函数容器来接收st…...
C语言的数据结构:树与二叉树(哈夫曼树篇)
前言 上篇讲完了二叉树,二叉树的查找性能要比树好很多,如平衡二叉树保证左右两边节点层级相差不会大于1,其查找的时间复杂度仅为 l o g 2 n log_2n log2n,在两边层级相同时,其查找速度接近于二分查找。1w条数据&am…...
docker 安装syslog
Syslog-ng是一个可靠、多功能的日志管理系统,用于收集日志并将其转发到指定的日志分析工具。 使用Docker CLI方式搭建 步骤 1: 拉取Syslog-ng镜像 首先,需要从Docker Hub拉取Syslog-ng的官方镜像。 docker pull balabit/syslog-ng:latest 步骤 2: 启动…...
什么是无头浏览器?
简而言之,无头浏览器是没有图形用户界面 (GUI) 的 Web 浏览器。GUI 包括用户与之交互的数字元素,例如按钮、图标和窗口。但是,关于无头浏览器,您需要了解的还有很多。 在本文中,您将了解什么是…...
【面试干货】与的区别:位运算符与逻辑运算符的深入探讨
【面试干货】&与&&的区别:位运算符与逻辑运算符的深入探讨 1、&:位运算符2、&&:逻辑运算符3、&与&&的区别 💖The Begin💖点点关注,收藏不迷路💖 & 和 …...
搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境(DAP-LINK: N32G45XVL-STB)
目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 FSP和KEIL产生测试项目 2.1 FSP生成项目 2.2 Keil中配置 3 硬件连接框图 4 一个测试案例 4.1 功能介绍 4.2 定时器函数 5 测试 搭建Renesas R7FA8D1BHECBD-BTB的开发调试环境(…...
探索人工智能和LLM对未来就业的影响
近年来,人工智能(AI)迅猛发展,引发了人们的兴奋,同时也引发了人们对就业未来的担忧。大型语言模型(LLM)就是最新的例子。这些强大的人工智能子集经过大量文本数据的训练,以理解和生成…...
钓鱼网站原理与攻防
知识点:LAMP平台部署,Web架构分析,钓鱼网站原理与搭建 中间件: 中间件是一种独立的软件,位于客户机和服务器之间,主要用于在网络环境中进行数据的传输和通信。它充当客户端和服务端之间的桥梁,…...
避开这5个坑,你的癫痫脑电AI模型准确率能翻倍:从数据标注到特征工程实战
避开这5个坑,你的癫痫脑电AI模型准确率能翻倍:从数据标注到特征工程实战 在医疗AI领域,癫痫脑电信号分析一直是个充满挑战的课题。许多开发者满怀信心地构建模型,却在验证阶段遭遇性能瓶颈——准确率停滞不前,误报率居…...
告别迷茫!在嵌入式Linux上用libwebsockets v4.0实现WebSocket客户端(含SSL配置避坑)
嵌入式Linux实战:libwebsockets v4.0客户端开发与SSL避坑指南 当树莓派的GPIO引脚需要与云端实时同步数据时,WebSocket往往是嵌入式开发者的首选协议。但面对内存仅512MB的ARMv7开发板,选用一个既支持SSL加密又能兼容C99标准的轻量级库&#…...
LearningX:构建结构化开发者知识体系,从基础到架构的实践指南
1. 项目概述:一个面向开发者的系统性学习仓库最近在GitHub上看到一个挺有意思的项目,叫“LearningX”。光看名字,你可能会觉得这又是一个普通的“Awesome-XXX”列表,或者是一堆学习资料的简单堆砌。但当我点进去,花了一…...
VHD2VL:破解硬件描述语言转换难题的开源解决方案
VHD2VL:破解硬件描述语言转换难题的开源解决方案 【免费下载链接】vhd2vl 项目地址: https://gitcode.com/gh_mirrors/vh/vhd2vl 在FPGA和ASIC设计领域,技术团队常常面临VHDL与Verilog两种硬件描述语言之间的转换挑战。当项目需要跨语言协作、工…...
荣品RV1126 SDK编译避坑指南:从环境配置到分区调整,手把手解决常见编译错误
RV1126 SDK编译实战:从环境搭建到分区优化的全流程解决方案 1. 开发环境配置与初始化 RV1126开发环境的搭建是整个开发流程的第一步,也是后续所有工作的基础。一个稳定、高效的开发环境能够显著提升开发效率,减少不必要的错误。 首先需要确保…...
高效跨平台游戏模组下载:WorkshopDL完全指南
高效跨平台游戏模组下载:WorkshopDL完全指南 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在Epic Games Store、GOG或其他非Steam平台购买了游戏࿰…...
NCM格式转换实战指南:ncmdumpGUI全面解析
NCM格式转换实战指南:ncmdumpGUI全面解析 【免费下载链接】ncmdumpGUI C#版本网易云音乐ncm文件格式转换,Windows图形界面版本 项目地址: https://gitcode.com/gh_mirrors/nc/ncmdumpGUI 你是否曾为网易云音乐下载的NCM格式音乐无法在其他设备播…...
Qdrant客户端库实战:从向量数据库连接到生产级应用开发
1. 项目概述:从向量数据库到应用落地的桥梁如果你最近在折腾大模型应用,或者想给自己的产品加上一个“智能大脑”,那你大概率绕不开一个词:向量数据库。简单来说,它就像一个能理解“意思”的超级搜索引擎,不…...
Onekey:重构Steam Depot清单下载流程的现代化解决方案
Onekey:重构Steam Depot清单下载流程的现代化解决方案 【免费下载链接】Onekey Onekey Steam Depot Manifest Downloader 项目地址: https://gitcode.com/gh_mirrors/one/Onekey Onekey作为一款专为Steam Depot清单设计的自动化下载工具,通过其创…...
Helm-Intellisense:VS Code智能补全插件,提升values.yaml编写效率
1. 项目概述:为什么我们需要一个Helm智能补全工具?如果你和我一样,日常工作中大量使用Helm来管理Kubernetes应用,那你一定对编写values.yaml文件时那种“盲人摸象”的感觉深有体会。面对一个动辄几十上百行配置的Helm Chart&#…...
