JNI接口--实现Java调用C++

news/2025/1/8 16:02:13/文章来源:https://www.cnblogs.com/plus301/p/18659182

1、JNI原理概述

通常为了更加灵活高效地实现计算逻辑,我们一般使用C/C++实现,编译为动态库,并为其设置C接口和C++接口。用C++实现的一个库其实是一个或多个类的简单编译链产物,然后暴露其实现类的构造方法和纯虚接口类。这样就可以通过多态调用到库内部的实现类及其成员方法。进一步地,为了让不同库之间调用兼容,可以将C++接口进一步封装为一组C接口函数,C接口函数编译时不会添加复杂的函数签名,也不支持函数重载,可以方便其他C或C++客户程序调用。C接口函数的封装需要有"extern C{}"标识,以告诉编译器请使用C编译方式编译这些函数。

进一步地,为了方便上层应用调用C/C++库,如Android应用,可以为C++库封装Java接口。JDK中的JNI组件可以方便地实现在Java中调用C++库函数。基本调用原理如下:

  •  Java客户代码实现和native方法声明属于Java层,使用Java编译器编译。
  • JNI接口实现代码和C++库属于C++层,使用G++编译。

 这里假定C++类库已经预编译好了,有现成的so库和C接口使用。首先明确一点的就是,我们要为C++库封装一个Java接口,也即在Java层使用C++库暴露的所有函数,那么:

1、第一步,创建一个Java类,并按照C++库的接口函数声明,创建所有的native本地接口函数声明(可以是static的)。

2、第二步,将这些本地接口声明映射为C++ JNI接口声明,这一步是通过Java提供的工具按照既定的映射机制自动生成的。这也就保证了Java层能正确找到C++实现。( javac -h <directory> <source files

3、第三步,实现第二步自动生成的C++ JNI接口函数,在这些接口实现中,按需组织调用C++类库的接口函数,以得到需要的结果。所以,这里要注意的一点是,C++ JNI接口函数实现会编译为一个单独的动态库,并且动态链接所使用的C++类库。(这里没有尝试过静态库,按道理应该也是可以的)。此外,在C++ JNI函数实现中,按照类型签名规则,我们可以获取到从Java层传入的参数,也可以返回特定的数据到Java层。

4、第四步,在Java应用层使用 system.loadLibrary("libName.so"); 加载第三步编译生成的JNI so库,即可间接调用C++库函数。

PS:

1、JNI层类型和Java类型的对应关系,基本数据类型只是简单地加了前缀 j ,如 int <=> jint,double <=> jdouble,下面是一些对象类型(包含数组)的映射关系:

 

 2、签名规则对应表

 3、String字符串操作

1     // 在jni实现函数中把jstring类型的字符串转换为C风格的字符串,会额外申请内存
2     const char *str = env->GetStringUTFChars(string,0);
3     // 做检查判断
4     if (str == NULL) { return NULL; }
5     // do something
6 
7     // 使用完之后释放申请的内存
8     env->ReleaseStringUTFChars(string,str);
  • JNI支持将 jstring 转换成UTF编码和Unicode编码两种。因为Java默认使用Unicode编码,而C/C++默认使用UTF编码。所以使用 GetStringUTFChars(jstring string, jboolean* isCopy) 将 jstring 转换成UTF编码的字符串。其中,jstring 类型参数就是我们需要转换的字符串,而 isCopy 参数的值在实际开发中直接赋值为 0 或 NULL 就好了,表示深拷贝。
  • 当调用完 GetStringUTFChars 方法时别忘了对返回结果做完全检查。因为 JVM 需要为产生的新字符串分配内存空间,如果分配失败就会返回NULL,并且会抛出 OutOfMemoryError 异常,所以要对 GetStringUTFChars 的返回结果进行判断。
  • 当使用完 GetStringUTFChars 返回的字符串时,还不能忘了释放所申请的内存空间。调用 ReleaseStringUTFChars 方法进行释放。
  • 除了将 jstring 转换为 C 风格字符串,JNI 还提供了将 C 风格字符串转换为 jstring 类型。通过 NewStringUTF 函数可以将 UTF 编码的 C 风格字符串转换为 jstring 类型,通过 NewString 函数可以将 Unicode 编码的 C 风格字符串转换为 jstring 类型。这个 jstring 类型会自动转换成 Java 支持的 Unicode 编码格式。
  • 除了 jstring 和 C 风格字符串的相互转换之外,JNI 还提供了其他的函数:

 2、思考

1、目前即使编译Debug版本,调试还是无法进入到 JNI 实现层。有博客说可以通过attach进程可以进入,我尝试并没有成功。

2、JNI 接口传参和返回数据到Java层要注意数据类型匹配,签名要一致,否则会直接崩溃掉。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/865936.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Leaflet 实现离线瓦片资源 + 飞线迁徙 + 自定义标记点位实现

npm install leaflet 注意构建webpack配置module: {rules: [{test: /\.(png|jpg|gif|jpeg|svg)$/,include: /node_modules[\\/]leaflet/,use: [{loader: url-loader,options: {outputPath: static/images}}]}] } 注意外部资源代理方式proxy: {/cdn: {target: https:// + ip + :…

Training Transformers with 4-bit Integers

目录概符号说明4-bit FQTLearned Step Size QuantizationHadamard QuantizationBit Splitting and Leverage Score Sampling代码Xi H., Li C., Chen J. and Zhu J. Training transformers with 4-bit integers. NeurIPS, 2023.概 本文针对 4-bit 中训练中一些特点 (针对 transf…

python SQLAlchemy ORM——从零开始学习 02简单的增删查改

02 简单的增删查改 前情提要:承接了01中的engine以及User类 2-1 了解会话机制个人理解 在SQLAlchemy 增删查改中是依赖会话(Session)这个机制进行操作的,我个人的理解是用“会话“进行连接数据库周期的一系列管理操作(以下是ai生成对此会话的理解)ai理解 在 SQLAlchemy 中…

YASKAWA机械手维修DX100示教器通电无反应

安川机器人DX100示教器通电无反应可能由多种原因导致,以下是一些常见的原因及对应的解决方法:可能原因电源问题:电源线破损或电源插座接触不良。 硬件故障:示教器内部电路板或元件(如内存条、处理器或显示屏等)损坏。 软件问题:软件发生错误或版本不匹配。 其他故障:…

春节电商爆单背后的协作黑科技!

每到春节,电商平台的交易额都会迎来新一轮爆发。但你是否思考过,支撑这一庞大运作的团队如何在高压之下确保高效协作?答案或许就藏在你忽略的细节里:在线文档协作。 春节购物高峰的背后:团队协作挑战重重 春节期间,消费者习惯于提前囤年货、抢促销,购物高峰往往集中爆发…

Transformer、编码器、解码器、全连接FFN、自注意力机制、嵌入向量、残差连接层归一化

一.提出背景 Transformer最早是Google在2017年的Attention Is All You Need论文中提出,用于解决解决传统的序列到序列(Seq2Seq)模型在处理可变长序列时遇到的问题。(序列到序列:指的是模型的输入是一段序列,模型输出也是序列;比如语音识别中给模型一段中文语音序列,让模…

JS-22 字符串的方法_concat()

concat方法用于链接两个字符串,返回一个新字符串,不改变原字符串 var s1=zifuchuan var s2=tow s1.concat(s2)//"zifuchuantow" s1//"zifuchuan" 该方法可以接受多个参数 two.concat(zifuchuan,three)//"zifuchuanthreetwo" 如果参数不是字符串…

年货抢购狂潮来袭,协作效率如何提升?

每年春节,都是电商企业竞争最激烈的战场。从年前的大促销到年后的物流爆单,作为电商团队的一员,你是否为节日期间高强度的工作节奏而焦虑?特别是在跨部门协作时,沟通不畅、任务延误、文档混乱等问题是否成为了团队效率的致命瓶颈? 在这一背景下,在线文档协作成为了提升春…

ASE100N10-ASEMI中低压N沟道MOS管ASE100N10

ASE100N10-ASEMI中低压N沟道MOS管ASE100N10编辑:ll ASE100N10-ASEMI中低压N沟道MOS管ASE100N10 型号:ASE100N10 品牌:ASEMI 封装:TO-220 批号:最新 最大漏源电流:100A 漏源击穿电压:100V RDS(ON)Max:8.8mΩ 引脚数量:3 芯片个数: 沟道类型:N沟道MOS管、低压MOS管 …

raylib U1S05 - 添加一个开始页面

先来看效果 看之前让我吐个槽。刚才编辑一半,结果我手贱点了个退出登录,然后都没了˃̣̣̥᷄⌓˂̣̣̥᷅开始按钮的图片是用豆包AI生成的,然后用美图秀秀抠图,改颜色。懒得自己搞素材的同学保存下面的三个图,注意改名字。普通状态 鼠标放上去 鼠标点击start_normal.png …