Я пытаюсь выяснить, как создать виртуальную машину 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 была построена из обычной цепочки ржавчины, но у меня нет достаточно твердого контроля над владением и правилами линейного типа, чтобы предсказать, когда он будет освобожден , Тот факт, что указатель хранится в структуре, возвращаемой функцией, еще более усложняет ситуацию.