JNI开发流程

article/2025/7/26 9:51:44

一. 引言

        最近在做一个自己的项目,就是基于FastDDS封装一套JAVA库,让android和java应用可以使用dds的功能。

        由于FastDDS是使用C++编写的开源库,因此java的类库想要调用FastDDS的接口,需要额外编写一个JNI层的动态库对FastDDS的接口进行封装,并且通过注册函数的方式将JNI中的接口函数注册给上层的JAVA类库或者java应用,这样,JAVA就可以通过jni动态库中的函数间接调用到FastDDS中的接口了。

二. 流程图

        大致的流程就是jni层的so需要实现JNI_OnLoad函数,这个函数是JAVA导入jni的so后会调用的,在该函数中可以获取到JAVA层的JVM以及JNIENV指针,有必要在JNI蹭保存这个JVM指针,后面用的上,JNIEnv指针不需要保存,因为该指针和java线程绑定的。

        JNI_OnLoad中还有一个重要的操作需要用户自己实现的,就是向JAVA层注册jni中的native函数,这些可以被看做是导出函数,jni层会维护一个函数对应表格,格式大致如下:

// 导出函数表
// 第一项  jni函数在java中的函数名
// 第二项  jni函数的函数签名
// 第三项  jni函数在jni动态库中的函数名
static const JNINativeMethod methods[] = {{ "nativeCreate", "(Ljava/lang/String;Lcom/test/dds/lcbtest/Participant)Z", (void*)(fydds::jni::nativeCreate) },{ "nativeDestroySubscriber", "()V", (void*)(fydds::jni::nativeDestroySubscriber) },
};

        可以把jni中的函数理解为JAVA中有一个函数,然后进过java编译器编译出来的c++实现,只是jni中的这个JAVA函数需要用于自己用c++实现,然后注册到JAVA里面去。

        因此,在这个表格中,我们才需要申明这个函数的java签名,以便让JVM能够识别并且调用到这个jni函数。

        此外,在调用jni的JAVA代码中,还需要用public native void nativeCreate(); 这样的申明来表示这个函数是JNI中的函数,然后才可以在java代码中调用nativeCreate,如下:

        

三. 需要注意的地方

1. jni导出函数的格式

        jni导出函数有两种,一种属于是给类对象调用的,可以理解为是某个JAVA类的普通成员方法,另一种属于是可以全局调用的,可以理解为JAVA类的静态方法。

        第一种函数的函数申明中,前两个参数为JNIEnv*和jobject

        JNIEnv*可以理解为Jvm在当前调用线程的上下文,可以使用JNIEnv创建java对象,查找并且反射JVM已经加载的java类,方法,或者调用JAVA层的方法。

        jobjcet参数是调用该JNI函数的java层对象的引用。

        后面的参数就是有JAVA层和JNI层协商好,JNI层定义这些参数并且使用这些参数,而JAVA层调用该函数时传递这些参数。

        这种函数,在JAVA层申明的时候函数名前面没有static修饰符:

public class TestJNIBean{...public native String testCallMethod();  //非静态
}

        第二种函数的函数申明和前者一样前两个参数也是JNIEnv*和jobject,但是,第二个jobject参数代表的是JAVA的类本身(例如Myclass.class),而不是类对象(例如Myclass cla),其在JAVA层申明的时候函数名前面有static修饰符:

public class TestJNIBean{...public static native String testStaticCallMethod();//静态
}

2. JNIEnv的用途

        JNIEnv代表了JAVA层的运行环境,通过JNIEnv指针就可以对JAVA端代码进行操作了,例如如下操作:

  • NewObject: 创建Java类中的对象。
  • NewString: 创建Java类中的String对象。
  • NewArray: 创建类型为Type的数组对象。
  • GetField: 获取类型为Type的字段。
  • SetField: 设置类型为Type的字段的值。
  • GetStaticField: 获取类型为Type的static的字段。
  • SetStaticField: 设置类型为Type的static的字段的值。
  • CallMethod: 调用返回类型为Type的方法。
  • CallStaticMethod: 调用返回值类型为Type的static 方法。

        

3. GlobalRef和LocalRef

        前面说过JNI函数的第二个参数是个jobject,但是得注意这个jobject引用是在java栈上面的,也就是临时的,这个jobject就是一个LocalRef,当jni函数调用结束后,该引用就出栈变得无效了,因此不能直接保存,需要通过JNIEnv::NewGlobalRef将该jobject代表的栈上的JAVA对象引用变成全局的JAVA对象引用,JNIEnv::NewGlobalRef返回的就是一个全局的JAVA对象引用。

4. jni中调用JAVA方法

        JNI中调用JAVA方法很简单,就是通过反射,只要能有JNIEnv和反射到的JAVA方法的MethodID,就可以在JNI的native方法中反过来调用JAVA的方法。

        如果在JNI的本地方法(不是导出给JAVA用的,例如注册给FastDDS的回调函数)中,因为没有JNIEnv,没法调用JAVA方法,该怎么办?

        在JNI_OnLoad的时候我们保存了JVM指针的话,这里就可以将当前本地方法所在的本地线程挂到JVM上,就可以获得JNIEnv的指针了。

int status = _javaVM->AttachCurrentThread(&env, NULL);
if (status >= 0) {jobject j_message = env->NewDirectByteBuffer(const_cast<char *>(msg_str->data()), msg_str->size());

5. IsSameObject

        这个函数在JNIEnv中,用来比对两个java引用是否指向同一个java对象,例如我们在第一次JNI函数调用中保存了调用方java class的引用(通过NewGlobalRef),在第二次我们想比较是不是同一个JAVA对象调用了该方法,就可以用IsSameObject来比对这两个jobject是否引用了同一个java对象。


http://www.hkcw.cn/article/eUduHAGlEH.shtml

相关文章

powershell 中 invoke-expression 报错解决

打开powershell就出现这个报错&#xff1a; 网上搜了也没有很好的解决办法&#xff0c;抱着一点点期待&#xff0c;问了豆包 根据豆包的指示&#xff0c;在终端执行以下 几个命令&#xff0c;报错解决了&#xff08;开心万岁&#xff09; # 移除多余的引号和空路径 $pathArra…

交错推理强化学习方法提升医疗大语言模型推理能力的深度分析

核心概念解析 交错推理:灵活多变的思考方式 交错推理(Interleaved Reasoning)是一种在解决复杂问题时,不严格遵循单一、线性推理路径,而是交替、灵活应用多种推理策略的方法。这种思维方式与人类专家在处理复杂医疗问题时的思考模式更为接近,表现为一种动态、适应性强的…

【下载ECharts最简单的方法】

最简单下载ECharts的方法 对于简单项目&#xff0c;我们需要的echarts文件是echarts.min.js&#xff0c;以下是下载ECharts的最简单方法&#xff1a; 方法一&#xff1a;直接下载&#xff08;推荐初学者&#xff09; 访问ECharts官网&#xff1a;https://echarts.apache.org…

西藏建筑安全员 B 证考试中常见的 单选题及解析

西藏建筑安全员 B 证考试中常见单选题及解析&#xff0c;涵盖安全生产管理、法律法规、安全技术等核心考点&#xff0c;结合西藏地区建筑施工特点整理&#xff0c;帮助理解考试重点&#xff1a; 一、安全生产管理基础 1. 安全管理原则与制度 1、建筑施工安全管理的方针是&am…

案例分享--血管支架的径向力分布评估--DIC数字图像相关技术用于生物医学-高置信度DIC测量

医疗设备制造商有责任创造和确保高效且安全的产品&#xff0c;以守护人类的健康。EchoBio LLC公司的Kenneth Perry博士是植入式医疗设备实验验证行业的领导者和专家。Perry博士的一项研究任务是评估用于疏通血管阻塞的编织自膨胀支架的径向力分布。Perry博士特别需要关注径向力…

[Javascript进阶]JSON.stringify与JSON.parse详解

JSON.stringfy JSON.stringify 的核心作用是&#xff1a; &#x1f449; 将 JS 的对象、数组、基本类型转换为合法的 JSON 字符串。 手撕实现时&#xff0c;要考虑以下几个方面&#xff1a; 基本类型处理&#xff1a; string → 加上双引号&#xff0c;注意转义&#xff1b;nu…

VirtualBox给Rock Linux9.x配置网络

写这篇文章之前&#xff0c;先说明一下&#xff0c;我参考的是我之前写的《VirtualBox Linux网络配置》 我从CentOS7转到了Rock9&#xff0c;和配置Centos7一样&#xff0c;主流程没有变化&#xff0c;变化的是Rock9.x中的配置文件和使用的命令。 我再说一次&#xff0c;因为主…

逆向分析基础总结

一、了解计算机部件 CPU&#xff1a; 中央处理器。有三个重要的部件&#xff1a; 逻辑部件&#xff1a;负责算数运算&#xff0c;包括定点运算、浮点运算等。 寄存器部件&#xff1a;负责临时数据存储&#xff0c;一个CPU包含多个寄存器。 控制部件&#xff1a;负责发出指令所…

企业信息化集成方案:聚水潭·奇门数据对接金蝶云星空

聚水潭奇门数据集成到金蝶云星空&#xff1a;销售退货单更新方案 在企业信息化管理中&#xff0c;数据的高效流动和准确对接是实现业务流程自动化的关键。本文将分享一个实际案例&#xff0c;展示如何通过轻易云数据集成平台&#xff0c;将聚水潭奇门系统中的销售退货数据无缝…

多功能文档处理工具推荐

软件介绍 今天为大家介绍一款功能强大的文档编辑工具坤Tools&#xff0c;这是一款在吾爱论坛广受好评的办公软件。 软件背景 坤Tools是由吾爱论坛用户分享的软件&#xff0c;在论坛软件榜单上长期位居前列&#xff0c;获得了用户的一致好评。 软件性质 这是一款完全离线、…

软考-系统架构设计师-第十八章 面向服务架构设计理论与实践

面向服务架构设计理论与实践 18.1 SOA 的相关概念18.2 SOA 的发展历史18.3 SOA 的参考架构18.4 SOA 主要协议和规范18.5 SOA 设计的标准要求18.6 SOA 的作用与设计原则18.7 SOA 的设计模式18.8 构建 SOA 架构时应该注意的问题18.9 SOA 实施的过程 18.1 SOA 的相关概念 &#x…

AI书签管理工具开发全记录(五):后端服务搭建与API实现

文章目录 AI书签管理工具开发全记录&#xff08;四&#xff09;&#xff1a;后端服务搭建与API实现前言 &#x1f4dd;1. 后端框架选型 &#x1f6e0;️2. 项目结构优化 &#x1f4c1;3. API路由设计 &#x1f9ed;分类管理书签管理 4. 数据模型定义 &#x1f4be;分类模型&…

CentOS-stream-9 Zabbix的安装与配置

一、Web环境搭建部署Zabbix时&#xff0c;选择合适的MariaDB、PHP和Nginx版本非常重要&#xff0c;以确保兼容性和最佳性能。以下是建议版本&#xff1a;Zabbix 6.4 MariaDB&#xff1a;官方文档推荐使用MariaDB 10.3或更高版本。对于CentOS Stream 9&#xff0c;建议使用Maria…

Scratch节日 | 龙舟比赛 | 端午节

端午节快乐&#xff01; 这款专为孩子们打造的Scratch游戏——《龙舟比赛》&#xff0c;让你在掌控龙舟的竞速中&#xff0c;沉浸式体验中华传统节日的魅力&#xff01; &#x1f3ae; 游戏亮点 节日氛围浓厚&#xff1a;化身龙舟选手&#xff0c;在波涛汹涌的河流中展开刺激竞…

抢占先机!品牌如何利用软文营销领跑内容营销赛道?

在当今这个信息爆炸的时代&#xff0c;内容营销已成为品牌与消费者沟通的重要桥梁。而软文营销&#xff0c;作为内容营销的一种重要形式&#xff0c;更是以其独特的魅力和高效的传播力&#xff0c;成为众多品牌抢占市场先机的利器。本文将深入探讨品牌如何利用软文营销领跑内容…

用谷歌云服务器可以做些什么?

解锁云端无限可能 在当今数字化飞速发展的时代&#xff0c;云计算技术犹如一股强大的动力&#xff0c;推动着各行各业的变革与创新。而谷歌云服务器&#xff0c;作为云计算领域的佼佼者&#xff0c;正以其卓越的性能和丰富的功能&#xff0c;为全球用户开启一扇通往全新数字世界…

Jetson Orin Nano - SONY imx415 camera驱动开发

目录 前言: 调试准备工作: 修改内核默认打印等级 一、imx415驱动开发 1、硬件接线 2、设备树修改 2.1 创建 tegra234-p3767-camera-p3768-imx415-C-4lane.dtsi 文件 2.2 tegra234-p3767-camera-p3768-imx415-C-4lane.dtsi 添加到设备树 2.3 编译设备树 3、imx415驱动…

Linux ClearOS yum无法使用解决备忘

前述 一个长期未使用的系统ClearOS Linux系统&#xff0c;属于CentOS家族&#xff0c;该系统用于网络设备。现在继续使用时&#xff0c;发现通过yum命令无法更新或下载软件。在这里记录一下解决该问题的过程。 问题 SSL证书问题 问题描述 问题现象如下所示&#xff0c;执行…

Bonjour

Bonjour 是苹果的一套零配置网络协议&#xff0c;用于发现局域网内的其他设备并进行通信&#xff0c;比如发现打印机、手机、电视等。 一句话&#xff1a;发现局域网其他设备和让其他设备发现。 Bonjour 可以完成的工作 IP 获取名称解析搜索服务 实际应用场景示例&#xff0…

day16 数组的常见操作和形状

目录 Numpy数组基础知识 数组的维度 数组的秩 数组的简单创建 zeros创建数组 ones创建数组 arange创建数组 数组的随机化创建 数组的遍历 数组的运算 数组的索引 一维数组索引 二维数组索引 三维数组索引 SHAP值的深入理解 知识点&#xff1a; numpy数组的创建&#xff1a;简单…