указатели, извлеченные из CString ржавчины, живут достаточно долго, чтобы оставаться действительными при вызове JNI_CreateJavaVM? - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь выяснить, как создать виртуальную машину Java из программы ржавчины, чтобы я мог использовать библиотеку батика для рендеринга некоторых SVG.

Пока у меня есть следующий код:

extern crate jni_sys;

use std::os::raw::{c_void, c_char};
use jni_sys::{JavaVM, JavaVMInitArgs, JNIInvokeInterface_, JNI_TRUE, JavaVMOption, JNIEnv, JNI_VERSION_1_6};
use std::ffi::CString;

#[link(name="exp1")]
extern "C" {
    fn bacon()->i32;
}

fn main() {
    let (jvm,env) = make_jvm();

    println!("{:p}=jvm\t{:p}=env", jvm, env);
}

fn make_jvm() -> (*mut JavaVM, *mut JNIEnv)
{
    let mut jvm : *mut JavaVM;
    let mut env: *mut JNIEnv;

    jvm = std::ptr::null_mut();
    env = std::ptr::null_mut();

    let mut args = assemble_jvm_args(JNI_VERSION_1_6, vec![]);
    unsafe {
        jni_sys::JNI_CreateJavaVM(&mut jvm as *mut _,
                                  &mut env as *mut _ as *mut *mut c_void,
                                  &mut args as *mut _ as *mut c_void);
    }

    return (jvm, env);
}

fn assemble_jvm_args(version: i32, opts: Vec<CString> ) -> JavaVMInitArgs
{

    let mut joa : Vec<JavaVMOption>;
    if (true) {
        let b: *mut c_void = std::ptr::null_mut();
        joa = opts.into_iter()
            .map(|o| JavaVMOption {
                optionString: o.as_ptr() as *mut _,
                extraInfo: b,
            }).collect();

    } else {
        let mut jo: [JavaVMOption; 0] = [];
        joa = Vec::new();
    }

    let mut args = JavaVMInitArgs {
        version: version,
        nOptions: joa.len() as i32,
        options: joa.as_mut_ptr(),
        ignoreUnrecognized: JNI_TRUE,
    };
    args
}

Меня беспокоит то, что *mut c_char, используемый для JavaVMOption.optionString, может не прожить достаточно долго или, наоборот, протечь.

Они приходят от параметра opts: Vec<CString> к assemble_jvm_args fn и являются результатом вызова .as_ptr(). Затем они живут в Vec<JavaVMOption>, и указатель на данные этого вектора присваивается JavaVMInitArgs.options, а JavaVMInitArgs возвращается из функции и передается как указатель на JNI_CreateJavaVM.

Я предполагаю, что *mut c_char был выделен в куче, когда строка CString была построена из обычной цепочки ржавчины, но у меня нет достаточно твердого контроля над владением и правилами линейного типа, чтобы предсказать, когда он будет освобожден , Тот факт, что указатель хранится в структуре, возвращаемой функцией, еще более усложняет ситуацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...