JNI 本地方法调用 Java 静态方法 和 实例方法对比;通过本地方法创建 Java 对象;本地方法访问 Java 数组元素;本地方法错误返回给 Java
以下是针对 Java JNI 的详细代码示例和对比分析:
一、调用 Java 静态方法 vs 实例方法
Java 示例类
public class JNIExample {public static void staticMethod(int value) {System.out.println("Static Method: " + value);}public void instanceMethod(String msg) {System.out.println("Instance Method: " + msg);}
}
JNI 实现代码
extern "C" JNIEXPORT void JNICALL Java_JNIExample_callMethods(JNIEnv *env, jobject obj) {// 1. 调用静态方法jclass cls = env->GetObjectClass(obj); // 或直接 FindClass("JNIExample")jmethodID staticMid = env->GetStaticMethodID(cls, "staticMethod", "(I)V");env->CallStaticVoidMethod(cls, staticMid, 42); // 参数为 int 42// 2. 调用实例方法jmethodID instanceMid = env->GetMethodID(cls, "instanceMethod", "(Ljava/lang/String;)V");jstring jmsg = env->NewStringUTF("Hello from JNI");env->CallVoidMethod(obj, instanceMid, jmsg); // 需要对象实例 obj
}
对比表格
| 对比项 | 静态方法调用 | 实例方法调用 |
|---|---|---|
| 方法ID获取 | GetStaticMethodID | GetMethodID |
| 调用函数 | CallStaticVoidMethod等 | CallVoidMethod等 |
| 参数 | 需要类对象(cls) | 需要对象实例(obj) |
| 适用场景 | 调用类的静态方法 | 调用特定对象的实例方法 |
| 注意事项 | 无需对象实例 | 必须确保对象实例有效 |
二、通过本地方法创建 Java 对象
Java 类(带构造器)
public class Person {public String name;public Person(String name) {this.name = name;}
}
JNI 实现代码
extern "C" JNIEXPORT jobject JNICALL Java_JNIExample_createObject(JNIEnv *env, jobject obj) {// 1. 获取类对象和构造方法IDjclass personCls = env->FindClass("Person");jmethodID constructor = env->GetMethodID(personCls, "<init>", "(Ljava/lang/String;)V");// 2. 创建新对象并调用构造器jstring jname = env->NewStringUTF("Alice");jobject personObj = env->NewObject(personCls, constructor, jname);return personObj; // 返回新对象给Java层
}
三、访问 Java 数组元素
Java 示例
public class JNIArrayExample {public native void processArray(int[] arr);
}
JNI 实现代码
extern "C" JNIEXPORT void JNICALL Java_JNIArrayExample_processArray(JNIEnv *env, jobject obj, jintArray arr) {// 1. 获取数组长度和元素指针jsize length = env->GetArrayLength(arr);jint* elements = env->GetIntArrayElements(arr, nullptr);// 2. 访问/修改元素(示例:打印所有元素)for (jsize i = 0; i < length; i++) {printf("Element %d: %d\n", i, elements[i]);}// 3. 释放资源(避免内存泄漏)env->ReleaseIntArrayElements(arr, elements, 0); // 0表示不复制回Java数组
}
四、JNI 异常处理(错误返回给 Java)
Java 示例
public class JNIExceptionExample {public native void riskyMethod();
}
JNI 实现代码
extern "C" JNIEXPORT void JNICALL Java_JNIExceptionExample_riskyMethod(JNIEnv *env, jobject obj) {// 1. 检查异常发生if (/* 某些错误条件 */) {// 2. 抛出Java异常(需提前注册异常类)jclass exceptionCls = env->FindClass("java/lang/RuntimeException");env->ThrowNew(exceptionCls, "JNI Error: Something went wrong!");}
}
Java 异常捕获
try {JNIExceptionExample example = new JNIExceptionExample();example.riskyMethod();
} catch (RuntimeException e) {System.out.println("Caught exception: " + e.getMessage());
}
关键总结
| 操作类型 | JNI 函数/方法 | 注意事项 |
|---|---|---|
| 调用静态方法 | GetStaticMethodID + CallStatic... | 需要类对象 cls |
| 调用实例方法 | GetMethodID + Call... | 需要对象实例 obj |
| 创建对象 | GetMethodID(构造器) + NewObject | 构造器方法名是 <init> |
| 访问数组 | GetIntArrayElements 等 | 必须调用 Release... 避免内存泄漏 |
| 抛出异常 | ThrowNew | 需要提前查找异常类 FindClass |
通过以上示例和对比,可以清晰理解 JNI 中不同操作的实现方式和关键差异。
相关文章:
JNI 本地方法调用 Java 静态方法 和 实例方法对比;通过本地方法创建 Java 对象;本地方法访问 Java 数组元素;本地方法错误返回给 Java
以下是针对 Java JNI 的详细代码示例和对比分析: 一、调用 Java 静态方法 vs 实例方法 Java 示例类 public class JNIExample {public static void staticMethod(int value) {System.out.println("Static Method: " value);}public void instanceMetho…...
AWS Lambda 深度解析:构建高效无服务器应用的实战指南
在2025年的云计算生态中,AWS Lambda 作为无服务器计算的代表,以其按需执行、高可扩展性和零运维成本的优势,成为开发者构建现代应用的首选。无论是快速原型开发还是生产级系统,Lambda 都能大幅提升效率。然而,如何充分…...
网络爬虫-2:基础与理论
一.同步加载与异步加载 1.1同步加载定义: 页面所有内容一起加载出来,当某一个数据加载有问题,整个页面就不会加载出来(如HiFiNi音乐网站),所以又叫阻塞模式 1.2爬取步骤: 看netword->document 2.1异步加载定义: 数据是分开加载的,当某一份数据有异常时,不影响其他数据…...
从零构建大语言模型全栈开发指南:第二部分:模型架构设计与实现-2.1.2多头注意力扩展与掩码机制(因果掩码与填充掩码)
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 2.1.2 多头注意力扩展与掩码机制(`因果掩码与填充掩码`)1. 多头注意力机制:分治策略的数学实现1.1 多头注意力核心公式2. 逐行代码实现2.1 多头拆分与合并3. 掩码机制:注意力控制的核心技术3.1 因果…...
Oracle 19C 备份
在 Oracle 19c 中,备份数据库通常使用 RMAN(Recovery Manager) 工具,它是 Oracle 提供的官方备份和恢复工具。以下是通过 RMAN 备份 Oracle 19c 数据库的详细步骤和命令。 一、RMAN 基本概念 RMAN 是 Oracle 的备份和恢复工具&am…...
[项目]基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050配置与读取
基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050 一.芯片介绍二.配置I2C三.编写驱动四.读取任务的测试五.MPU6050六轴数据的校准 一.芯片介绍 芯片应该放置在PCB中间,X Y轴原点,敏感度131表示范围越小越灵敏。理想状态放置在地面上X,Y…...
后端学习day1-Spring(八股)--还剩9个没看
一、Spring 1.请你说说Spring的核心是什么 参考答案 Spring框架包含众多模块,如Core、Testing、Data Access、Web Servlet等,其中Core是整个Spring框架的核心模块。Core模块提供了IoC容器、AOP功能、数据绑定、类型转换等一系列的基础功能,…...
【赵渝强老师】在Docker中运行达梦数据库
Docker是一个客户端服务器(Client-Server)架构。Docker客户端和Docker守护进程交流,而Docker的守护进程是运作Docker的核心,起着非常重要的作用(如构建、运行和分发Docker容器等)。达梦官方提供了DM 8在Doc…...
Python电影市场特征:AR模型时间序列趋势预测、热图可视化评分影响分析IMDb数据|附数据代码
原文链接:https://tecdat.cn/?p41214 分析师:Zhiheng Lin 在数字时代,电影产业的数据分析已成为洞察市场趋势与用户偏好的重要工具。本专题合集聚焦印度电影市场,通过IMDb数据集(IMDb Movies Dataset)的深…...
扭蛋机小程序开发,潮玩娱乐消费风口下的机遇
随着Z世代消费能力的提升和盲盒经济的火爆,扭蛋文化正迎来爆发式增长。 扭蛋机作为一种充满惊喜感的消费模式,正从线下走向线上,并借助移动互联网实现了数字化转型。线上扭蛋机小程序不仅延续了传统扭蛋的趣味性,还通过数字化手段…...
网络安全基础:五类安全服务、八种安全机制与OSI七层模型的全面解析
目录 引言 五类安全服务 2.1 认证服务 2.2 访问控制 2.3 数据保密性 2.4 数据完整性 2.5 不可否认性 八种安全机制 3.1 加密机制 3.2 数字签名 3.3 访问控制机制 3.4 数据完整性机制 3.5 认证交换机制 3.6 流量填充机制 3.7 路由控制机制 3.8 公证机制 OSI七层…...
各类神经网络学习:(五)LSTM 长短期记忆(上集),结构详解
上一篇下一篇RNN(下集)待编写 LSTM(长短期记忆) 参考知乎文章《人人都能看懂的LSTM介绍及反向传播算法推导(非常详细) - 知乎》,部分图片也进行了引用。 参考视频教程《3.结合例子理解LSTM_哔哩…...
Python项目-基于Python的网络爬虫与数据可视化系统
1. 项目简介 在当今数据驱动的时代,网络爬虫和数据可视化已成为获取、分析和展示信息的重要工具。本文将详细介绍如何使用Python构建一个完整的网络爬虫与数据可视化系统,该系统能够自动从互联网收集数据,进行处理分析,并通过直观…...
Spring Boot 自定义 Starter 组件的技术指南
1、简述 Spring Boot 通过 Starter 机制,让开发者可以快速集成第三方组件。在企业级开发中,我们常常需要封装自己的 Starter 组件,以提高代码复用性,简化配置,并实现可插拔的模块化开发。 Spring Boot Starter 机制 …...
计算机二级WPS Office第九套WPS演示
解题过程...
计算机网络-2 物理层
【考纲内容】 (一)通信基础 信道、信号、带宽、码元、波特、速率、信源与信宿等基本概念; 奈奎斯特定理与香农定理;编码与调制; 电路交换、报文交换与分组交换;数据报与虚电路① 视频讲解 (二…...
三分钟掌握音频提取 | 在 Rust 中优雅地处理视频音频
前言 在多媒体开发中,从视频中提取音频是一个常见需求。比如,你可能需要分离背景音乐来单独欣赏,或者提取对白用于语音分析,甚至为视频生成字幕。无论目的如何,音频提取都是多媒体处理中的基础操作。 传统上…...
Redis集群哨兵相关面试题
目录 1.Redis 主从复制的实现原理是什么? 详解 补充增量同步 replication buffer repl backlog buffer 2.Redis 主从复制的常见拓扑结构有哪些? 3.Redis 复制延迟的常见原因有哪些? 4.Redis 的哨兵机制是什么? 主观下线和客观下线 哨兵leader如何选出来的&#x…...
Shopify Checkout UI Extensions
结账界面的UI扩展允许应用开发者构建自定义功能,商家可以在结账流程的定义点安装,包括产品信息、运输、支付、订单摘要和Shop Pay。 Shopify官方在去年2024年使用结账扩展取代了checkout.liquid,并将于2025年8月28日彻底停用checkout.liquid…...
Perl 环境安装指南
Perl 环境安装指南 引言 Perl是一种广泛使用的解释型、动态编程语言,以其强大的文本处理能力和灵活性著称。本文将为您详细介绍Perl环境的安装过程,包括系统要求、安装步骤以及注意事项。 系统要求 在安装Perl之前,请确保您的计算机满足以下基本要求: 操作系统:Window…...
MOSN(Modular Open Smart Network)-04-TLS 安全链路
前言 大家好,我是老马。 sofastack 其实出来很久了,第一次应该是在 2022 年左右开始关注,但是一直没有深入研究。 最近想学习一下 SOFA 对于生态的设计和思考。 sofaboot 系列 SOFAStack-00-sofa 技术栈概览 MOSN(Modular O…...
Softmax 回归 + 损失函数 + 图片分类数据集
Softmax 回归 softmax 回归是机器学习另外一个非常经典且重要的模型,是一个分类问题。 下面先解释一下分类和回归的区别: 简单来说,分类问题从回归的单输出变成了多输出,输出的个数等于类别的个数。 实际上,对于分…...
重温Ubuntu 24.04 LTS
用户调整 # 创建新用户 sudo adduser newusername # 设置新用户的密码 sudo passwd newusername # 将新用户添加到 sudo 组 sudo usermod -aG sudo newusername # 修改ssh访问权限 sudo nano /etc/ssh/sshd_config # 将新用户加入,此时root将无法访问 AllowUsers n…...
FreeRTOS学习(十):任务调度器挂起与恢复机制详解
FreeRTOS学习(十):任务调度器挂起与恢复机制详解 文章目录 FreeRTOS学习(十):任务调度器挂起与恢复机制详解简介一、 任务挂起与恢复的API函数1.1 任务挂起函数1.2 任务恢复函数 二、重要特性与临界区的区别…...
【C++】内存模型分析
在 C 语言中,程序运行时的内存通常被划分为以下几个区域: 代码区(Text Segment)常量区(Constant Segment)全局/静态区(Data Segment,包含静态数据段和 BSS 段)堆区&…...
Vue2+OpenLayers携带请求头加载第三方瓦片数据
目录 一、案例截图 二、安装OpenLayers库 三、代码实现 一、案例截图 在对接一些第三方GIS地图的时候,需要携带请求头来验证身份,从而获取相应的瓦片数据,这时候我们需要改造一下WMTS服务的调用方式,效果如图所示: 二、安装OpenLayers库 npm install ol 三、代码实现…...
智能汽车图像及视频处理方案,支持视频实时拍摄特效能力
在智能汽车日新月异的今天,美摄科技作为智能汽车图像及视频处理领域的先行者,凭借其卓越的技术实力和前瞻性的设计理念,为全球智能汽车制造商带来了一场视觉盛宴的革新。美摄科技推出智能汽车图像及视频处理方案,一个集高效性、智…...
Vue 中如何使用 v-model 实现自定义组件的双向绑定?
在 Vue 中,使用 v-model 实现自定义组件的双向绑定需要遵循一套特定的规则。以下是关于如何实现这一功能的详细步骤和示例。 1. 理解 v-model 在 Vue 中,v-model 实际上是语法糖,它在内部实现了 :value 和 @input 的结合。使用 v-model 的自定义组件需要支持以下两个属性:…...
数据结构--顺序表(实现增删改查)
三个文件(Mytest.c 、MySeqList.c 、 MySeqList.h) Mytest.c测试函数 MySeqList.c 函数定义 MySeqList.h函数声明 增删改查的步骤: 初始化 增加元素 • 尾插:先检查顺序表空间是否足够,若不足则进行扩容&#x…...
【android】补充
3.3 常用布局 本节介绍常见的几种布局用法,包括在某个方向上顺序排列的线性布局,参照其他视图的位置相对排列的相对布局,像表格那样分行分列显示的网格布局,以及支持通过滑动操作拉出更多内容的滚动视图。 3.3.1 线性布局Linea…...
