如何快速使用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架构分析,钓鱼网站原理与搭建 中间件: 中间件是一种独立的软件,位于客户机和服务器之间,主要用于在网络环境中进行数据的传输和通信。它充当客户端和服务端之间的桥梁,…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
