- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
本博客所有文章除特别声明外,均采用CC BY-NC-SA 4.0许可协议。转载请注明来自 唯你 。
JAVA 与 Rust 互操作让 Rust 可以背靠 Java 大生态来做更多事情,而 Java 也可以享受 Rust 语言特性的内存安全,所有权机制,无畏并发.
互操作的典型场景包括:
JNI 是 Java 虚拟机的一部分,JVM 在启动时为每个线程创建一个 JNI 环境。JNI 环境包括指向 JVM 内部数据结构的指针,这些数据结构用于存储 Java 对象、方法和字段的信息.
JNIEnv
是一个指向结构体的指针,代表当前线程的 JNI 环境。它包含所有 JNI 相关函数的指针,让你能在本地代码中使用这些函数。每个线程都有自己独立的JNIEnv
,所以不能在不同线程间传递这个指针。JNIEnv
视为一个"翻译器"。当 Rust 代码需要与 Java 交互时,它通过这个"翻译器"发送请求,当调用 Java 方法或获取 Java 对象的属性。每个线程都拥有自己独立的"翻译器",这确保了各线程与 Java 交互时的独立性。JNIEnv
指针。JNIEnv
,保证线程安全。新线程需调用AttachCurrentThread
获取对应JNIEnv
。在 Rust 生态中使用 jni 0.21.1 库可以实现与 Java 代码的交互.
该项目为 Rust 提供了完整的 JNI 绑定,允许:
使用 Rust 代码与 Java 库进行交互,调用 Java 方法和访问 Java 对象.
从 Rust 代码中使用 Java 类和接口.
实现跨语言的高效数据交换.
利用 Rust 的性能优势和 Java 的成熟生态系统 。
跨平台 UI 框架 Flutter 源码中的 MethodChannel 实现了 Dart 与 Android 层的通信,其底层 C++也是通过 JNI 调用插件中的 onMethodCall 来实现的。这与上述 jni 0.21.1 采用了相同的思路,但存在以下不同点:
jni
库提供了一种更安全的方式来处理 Java 对象和方法调用。它利用 Rust 的所有权系统来减少潜在的内存错误,使得在 Rust 中使用 JNI 时更易于管理资源和避免常见错误。示例源码请阅读原文,见原文底部源码获取 。
在 Windows 11 环境下运行示例时,笔者遇到了两个问题:
以下是解决这些问题的方法:
mingw32-make
工具(通常随 MinGW-w64 一起安装)//当前示例中是makefile,直接执行mingw32-make -f makefile即可
mingw32-make -f YourMakefileName
举例来说,笔者在 C:\Users\xxx.cargo 目录下配置了 config.toml 文件:
[build]
target = "aarch64-linux-android"
这导致在 Windows 上使用 mingw32-make 来编译针对 Android 平台的 Rust .so 文件,造成了混乱并引发了莫名其妙的编译错误。解决方法是删除不必要的 config.toml 文件,确保当前运行环境与目标平台(如 Windows)一致。.
输出结果:
Hello, josh!
[B@2f92e0f4
factCallback: res = 720
counterCallback: count = 1
counterCallback: count = 2
counterCallback: count = 3
counterCallback: count = 4
counterCallback: count = 5
Invoking asyncComputation (thread id = 1)
asyncCallback: thread id = 23, progress = 0%
asyncCallback: thread id = 23, progress = 10%
asyncCallback: thread id = 23, progress = 20%
asyncCallback: thread id = 23, progress = 30%
asyncCallback: thread id = 23, progress = 40%
asyncCallback: thread id = 23, progress = 50%
asyncCallback: thread id = 23, progress = 60%
asyncCallback: thread id = 23, progress = 70%
asyncCallback: thread id = 23, progress = 80%
asyncCallback: thread id = 23, progress = 90%
asyncCallback: thread id = 23, progress = 100%
让我们深入分析示例中 asyncComputation 的流程。其核心目的是在 Rust 端执行一个异步计算,同时 Rust 端会调用 Java 端来报告计算进度.
整体流程图说明:
这个过程展示了 Java 调用 Rust(步骤 1)和 Rust 回调 Java(步骤 4)的双向交互.
JNIEnv
参数:详见上述相关概念中的解释。JClass
:代表调用此本地方法的 Java 类引用,主要用于访问类级别的静态方法和字段。callback
:Java 中新创建的 HelloWorld 对象实例。env
对象不支持线程间传递和共享(仅实现了 Send),而 JVM 支持。通过 JVM 对象可在线程间传递,并最终获得 env
。JNIEnv
,确保线程安全。在新线程中需调用 AttachCurrentThread
获取对应的 JNIEnv
。env
反向调用 Java 代码。调用对象是新创建的 HelloWorld 实例,回调方法是其中的 asyncCallback。在 JNI 中,"(I)V"
是方法签名,描述了 Java 方法的参数和返回类型。"(I)V"
表示接受一个整数参数并返回 void
的方法。在这里,asyncCallback 方法接收一个整数(progress
)作为参数,无返回值。https://github.com/jni-rs/jni-rs 。
JNI APIs and Developer Guides 。
Leveraging Rust in our high-performance Java database 。
最后此篇关于一文解秘Rust如何与Java互操作的文章就讲到这里了,如果你想了解更多关于一文解秘Rust如何与Java互操作的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!