【Rust NDK】动态注册和所有权间的纠纷

引言

前面几篇文章基本上将 jni-rs 介绍完了。然而,还有一个较为重要的部分没说明,也就是动态注册。毕竟是可以投入生产的东西了,动态注册这么重要的东西怎么能少?C/C++有的东西,我Rust也得有!那么,开撸!

开发环境

操作系统:Windows 11

编码软件:Visual Studio Code 1.93.1 | Android Studio Ladybug | 2024.2.1 Beta 1

正文

本文将对 ndk 在 rust 中的动态注册进行介绍,并且将重点说明这过程中 所有权 转移的情况。

创建Rust项目

老样子,我们正常创建一个 example_5 的lib项目,然后改造它。

image.png

image.png

接着,打开 lib.rs 开始编码。

image.png

和C/C++一样 jni-rs 也提供了 JNI_OnLoad 函数,接受两个参数。

然后,我们按照常规写法,将 jvm 存起来(第14行)。

这里使用的是Rust提供的 OnceLock 它支持多线程安全,并且只允许赋值一次,读取多次。

读取方式在第20行。

最后,返回 JNI_VERSION_1_6 (值得注意的是,当返回 JNI_VERSION_1_8 时app会崩溃)

动态注册

当准备工作完毕后,就可以实现上面的 //todo 了。

以下,就是动态注册的实现。

image.png

上图,第一个红色框我们将 env 改为了可变的变量,然后增加了第二个红框中的代码。

在第三个红色框中,使用NativeMehtod结构体来表示它是一个本地方法,而它的第三个值fn_ptr需要是一个C函数的指针表示,所以这里的 native_method 函数被强转为了C指针

我们打开它的实现,可以看到它也有相关说明,第二个值类型就决定了该动态注册的方法是否为 静态的,当类型为 JClass 时就表示该方法是静态方法,当类型为 JObject 时就表示该方法为实例方法

image.png

OK,Rust层到这儿就结束了。

编译出so文件后,我们就可以创建Android项目进行测试了。

cargo ndk -t armeabi-v7a -t arm64-v8a -o ./jniLibs build --release 

创建Android项目

image.png

然后跑一下,看一下效果。

所有权导致崩溃

果然,前面顺风顺水(前面的几篇文章只要是通过了Rust的编译检查,在Android这边基本上是直接跑起来的),现在呢,总算是遭到报应了。

image.png

那么,就需要重新打包,并导出符号表查看崩溃情况了。

直接运行一下 cargo ndk 发现它提供了一个命令行参数 --no-strip

image.png

修改一下编译so的命令。

cargo ndk --no-strip -t armeabi-v7a -t arm64-v8a -o ./jniLibs build --release

重新编译覆盖进android项目后,再来查看崩溃情况。

image.png

诶,出现了。从截图看在报错列表中,只有 native_method 这个方法是我们自己写的,那么原因就是它咯。

image.png

可这个就是一个简单创建字符串的方法呀,正当我百思不得其解时,问了问AI。

image.png

image.png

这才恍然大悟,原来是 借用 出现了问题。

被动态注册的 native_method 实际上是直接与jvm进行交互的,所以jvm传入的env实参应该是所有权的转移而并不是可变or不可变的引用 ,因此当我使用 env: &mut JNIEnv<'l> 时会照成app的崩溃。所以这里应该直接让 native_methodenv形参拿到所有权,也就是说将其修改为 env: JNIEnv<'l>mut env: JNIEnv<'l> 才对。

而对于 register_jni_natives 函数而言,它是直接在rust代码层就被直接调用(本身就是作为一个封装函数)那么自然就允许借用了。

image.png

好,我们按照gpt的提示,修改一下 native_method 的env形参。

image.png

再次编译,复制,替换,运行(记得clean)。

结果展示

image.png

本篇完~

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/22378,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?