1

我是生锈的新手,我正试图将我的头包裹在生命周期中。请考虑以下代码:

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.

4

1 回答 1

2

crate中命名JNIEnv了两种类型:jni

  1. jni::sys::JNIEnv:这是一个类型别名:type JNIEnv = *const JNINativeInterface_;
  2. jni::JNIEnv: 这是一个安全的包装jni::sys::JNIEnv

您不能简单地使用asto 在两者之间进行转换,因为它们是不相关的类型。实际上,在您的env()方法中,您只需 clone 即可self._env。此外,jni::JNIEnv它只是一个指针的包装器,并且克隆很便宜(它不是深拷贝),因此您可以通过值而不是通过引用来存储它self._env

jni::JNIEnv公开在两种类型之间转换的方法。jni::JNIEnv::from_rawjni::sys::JNIEnvjni::JNIEnv,然后jni::JNIEnv::get_native_interface到另一个方向。

于 2020-02-15T01:26:19.797 回答