本文详解在 Rust 中使用 JNI 调用 Java static void main(String[] args) 等带 String[] 参数的静态方法时,如何构造并传入 jobjectArray,涵盖 new_object_array、set_object_array_element 与 JValue::Object 的协同用法。
本文详解在 rust 中使用 jni 调用 java `static void main(string[] args)` 等带 `string[]` 参数的静态方法时,如何构造并传入 `jobjectarray`,涵盖 `new_object_array`、`set_object_array_element` 与 `jvalue::object` 的协同用法。
在 Rust 中通过 JNI 调用 Java 静态方法(如 main(String[]))时,核心难点在于:Java 的 String[] 参数必须以 jobjectArray 类型传入,且需显式构造、填充,并通过 JValue::Object 封装为可调用参数。这与 C/C++ 的 JNI API 行为一致,但 jni crate 提供了更安全、Rust 风格的封装。
首先需获取 java/lang/String 的 JClass,作为数组元素类型:
let string_class = env.find_class("java/lang/String")?;
使用 env.new_object_array(len, element_class, initial_element) 构造数组。注意第三个参数是“默认填充值”(用于初始化每个元素),通常用空字符串对象:
let empty_str = env.new_string("")?;let args_array = env.new_object_array(6, string_class, empty_str)?;// → args_array: JObjectArray,对应 Java 的 String[6]
对每个命令行参数,创建 JString 并写入指定索引:
立即学习“Java免费学习笔记(深入)”;
let args = [ "--username", "Test", "--version", "1.7.10", "--uuid", "4f19c3577b774731bcc663e536ebd108", "--accessToken", "12412412412", "--userProperties", "{}",];for (i, &arg) in args.iter().enumerate() { let jstring = env.new_string(arg)?; env.set_object_array_element(&args_array, i as i32, jstring)?;}
⚠️ 注意:set_object_array_element 的索引类型为 i32,切勿传入 usize 而未转换。
call_static_method 的第四个参数是 &[JValue]。由于 args_array 是对象数组,需转为 JObject 再包裹为 JValue::Object:
use jni::objects::JValue;env.call_static_method( class, // jclass "main", // method name "([Ljava/lang/String;)V", // signature &[JValue::Object(&JObject::from(args_array))], // ✅ 关键:包装为 JValue)?;
// 假设 env: JNIEnv, class: JClass 已就绪let string_class = env.find_class("java/lang/String")?;let empty_str = env.new_string("")?;let args_array = env.new_object_array(6, string_class, empty_str)?;let cli_args = [ "--username", "Test", "--version", "1.7.10", "--uuid", "4f19c3577b774731bcc663e536ebd108", "--accessToken", "12412412412", "--userProperties", "{}",];for (i, arg) in cli_args.iter().enumerate() { let jstr = env.new_string(arg)?; env.set_object_array_element(&args_array, i as i32, jstr)?;}env.call_static_method( class, "main", "([Ljava/lang/String;)V", &[JValue::Object(&JObject::from(args_array))],)?;
掌握这一模式后,你即可复用于任意接受 String[]、Object[] 或其他对象数组的 Java 静态方法调用——这是 Rust-JNI 互操作中最典型也最易出错的一环。