如何快速使用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架构分析,钓鱼网站原理与搭建 中间件: 中间件是一种独立的软件,位于客户机和服务器之间,主要用于在网络环境中进行数据的传输和通信。它充当客户端和服务端之间的桥梁,…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...