rust - 将具有生存期的借用引用强制转换为Rust中的原始指针

标签 rust jnienv raw-pointer

我是使用rust 的新手,正努力将自己的头缠住一生。请考虑以下代码:

use jni::JNIEnv;

pub struct CameraAppEngine<'a> {
    _env: &'a JNIEnv<'a>,
    _width: i32,
    _height: i32
}

impl<'a> CameraAppEngine<'a> {
    pub fn new(_env: &'a JNIEnv<'a>, _width: i32, _height: i32) -> CameraAppEngine {
        CameraAppEngine { _env, _width, _height }
    }

    pub fn env(&'a self) -> JNIEnv<'a> {
        JNIEnv::from_raw(self._env).unwrap() // error!
    }
}

JNIEnv::from_raw方法的类型签名为from_raw(ptr: *mut JNIEnv) -> Result<Self>,因此导致编译错误:
|         JNIEnv::from_raw(self._env).unwrap()
|                          ^^^^^^^^^ types differ in mutability
|
= note: expected raw pointer `*mut *const jni::sys::JNINativeInterface_`
                found reference `&'a jni::JNIEnv<'a>`

然后,我尝试了JNIEnv::from_raw(self._env as *mut JNIEnv<'a>).unwrap(),但是结果是:
|         JNIEnv::from_raw(self._env as *mut JNIEnv<'a>).unwrap() // error!
|                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected *-ptr, found struct `jni::JNIEnv`
|
= note: expected raw pointer `*mut *const jni::sys::JNINativeInterface_`
            found raw pointer `*mut jni::JNIEnv<'a>`

error[E0606]: casting `&'a jni::JNIEnv<'a>` as `*mut jni::JNIEnv<'a>` is invalid
--> native_app/src/camera_engine.rs:16:26
|
|         JNIEnv::from_raw(self._env as *mut JNIEnv<'a>).unwrap() // error!
|                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

如何从结构的引用中获取有效的JNIEnv?

干杯,谢谢您的宝贵时间!

更新

这是展示问题的一种较不人为的方法。

pub fn create_camera_session(&'a mut self, surface: jobject) {
    // error!
    let window = ffi::ANativeWindow_fromSurface(self._env as *mut JNIEnv<'a>, surface);
}

结果是:
error[E0606]: casting `&'a jni::JNIEnv<'a>` as `*mut jni::JNIEnv<'a>` is invalid

ANativeWindow_fromSurface的类型签名为ANativeWindow_fromSurface(env: *mut JNIEnv, surface: jobject) -> *mut ANativeWindow

最佳答案

JNIEnv箱中有两种名为jni的类型:

  • jni::sys::JNIEnv :这是类型别名:type JNIEnv = *const JNINativeInterface_;
  • jni::JNIEnv :这是jni::sys::JNIEnv的安全包装。

  • 您不能简单地使用as在两者之间进行转换,因为它们是不相关的类型。实际上,您可以在env()方法中克隆self._env。此外,jni::JNIEnv只是一个指针的包装器,克隆很便宜(它不是深拷贝),因此您可以按值存储它,而不是按引用存储在self._env中。
    jni::JNIEnv公开了在两种类型之间进行转换的方法。 jni::JNIEnv::from_raw jni::sys::JNIEnv变为jni::JNIEnv,而 jni::JNIEnv::get_native_interface 则相反。

    关于rust - 将具有生存期的借用引用强制转换为Rust中的原始指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60216847/

    相关文章:

    sql - 生成 SQL 字符串的 Rust 函数是否容易受到 SQL 注入(inject)的攻击?

    json - 编码泛型类型时生命周期参数的数量错误

    java - JNI - 向 C++ 发送一个大的 byte[] 缓冲区

    C++ 处理堆上的对象

    pointers - 为什么使用原始指针的链表中的节点会损坏?

    error-handling - Rust `From` 特征、错误、引用与 Box 和 `?` 运算符

    rust - 在Rust中使用char常量声明String

    android - 保存 JNIEnv* 的最佳方法是什么?

    java - JNI_CreateJavaVM函数方法不起作用,无法调试

    c++ - 进入智能指针,如何处理代表所有权?