英文:
JNI Rust how to pass arguments to call_static_method?
问题
以下是您要翻译的内容:
"这是我使用JNI的第一个项目。
我正在尝试从Rust中调用Java方法。
Java方法签名如下:
public static void main(String[] args) {...}
在Rust一侧,我创建了一个JavaVM,找到了类并尝试调用静态方法,但我不知道如何传递参数:
env.call_static_method(class, "main", "([Ljava/lang/String;)V", HowPassArgumentsThere?)
.expect("调用main方法失败");
据我了解,参数是一个字符串数组。我必须传递类似于这样的内容:
[
“—username”, “Test”,
“—version”, “1.7.10”,
“—uuid”, “4f19c3577b774731bcc663e536ebd108”,
“—accessToken”, “12412412412”,
“—userProperties”, “{}”
]
完整的代码可在此处找到:链接
我尝试按照C++中的方法创建了一个对象数组,如下所示:
jobjectArray str_array = Env->NewObjectArray(Env, 4, Env->FindClass(Env, 'java/lang/String'), Env->NewString(Env, NULL, 0));
Arguments[0] = '--username';
Arguments[1] = 'Player';
Arguments[2] = '--accessToken';
Arguments[3] = '12345';
Env->SetObjectArrayElement(Env, JavaObjectArray, 0, Env->NewString(Env, &Arguments[0]), strlen(Arguments[0]));
Env->SetObjectArrayElement(Env, JavaObjectArray, 1, Env->NewString(Env, &Arguments[1]), strlen(Arguments[1]));
Env->SetObjectArrayElement(Env, JavaObjectArray, 2, Env->NewString(Env, &Arguments[2]), strlen(Arguments[2]));
Env->SetObjectArrayElement(Env, JavaObjectArray, 3, Env->NewString(Env, &Arguments[3]), strlen(Arguments[3]));
env->CallStaticVoidMethod(class_Launch, env->GetStaticMethodID(class_Launch, "main", "([Ljava/lang/String;)V"), str_array);
jvm->DestroyJavaVM();
但在Rust中它不起作用。有任何想法吗?"
英文:
This is my first project using jni.
I am trying to invoke a Java method from Rust.
Java method signature looks like this:
public static void main(String[] args) {...}
On the Rust side, I create a JavaVM, find the class and try to call static method, but I don't know how to pass the arguments
env.call_static_method(class, "main", "([Ljava/lang/String;)V", HowPassArgumentsThere?)
.expect("Failed to invoke main method");
Arguments are an array of strings as I understand it. And I have to put something like this:
[
“—username”, “Test”,
“—version”, “1.7.10”,
“—uuid”, “4f19c3577b774731bcc663e536ebd108”,
“—accessToken”, “12412412412”,
“—userProperties”, “{}”
]
Full code available there: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=03c197068218a00b3e0a2d8f170dda16
i tried to create an object array according to how it's done in cpp
jobjectArray str_array = Env->NewObjectArray(Env, 4, Env->FindClass(Env, 'java/lang/String'), Env->NewString(Env, NULL, 0));
Arguments[0] = '--username';
Arguments[1] = 'Player';
Arguments[2] = '--accessToken';
Arguments[3] = '12345';
Env->SetObjectArrayElement(Env, JavaObjectArray, 0, Env->NewString(Env, &Arguments[0]), strlen(Arguments[0]));
Env->SetObjectArrayElement(Env, JavaObjectArray, 1, Env->NewString(Env, &Arguments[1]), strlen(Arguments[1]));
Env->SetObjectArrayElement(Env, JavaObjectArray, 2, Env->NewString(Env, &Arguments[2]), strlen(Arguments[2]));
Env->SetObjectArrayElement(Env, JavaObjectArray, 3, Env->NewString(Env, &Arguments[3]), strlen(Arguments[3]));
env->CallStaticVoidMethod(class_Launch, env->GetStaticMethodID(class_Launch, "main", "([Ljava/lang/String;)V"), str_array);
jvm->DestroyJavaVM();
But in Rust it doesn't work. Any ideas?
答案1
得分: 2
I solved the problem by spending a lot of time studying the documentation. Since I could not find information on the web (that's why I created the question), I'll leave the solution here.
To pass arguments to a method call, you need to do something like this:
// create Java array of objects (in our case, type string)
// 1 - one element of array
// stringClass - Java string class signature ("java/lang/String")
// env.new_string("") - initial element of array
let arguments: JObjectArray = env.new_object_array(1, stringClass, env.new_string("").unwrap()).unwrap();
// Set element at index 0
// &arguments - reference to our Java objects array
// 0 - element index (place at)
// env.new_string("--username") - the value we set at 0 index (create new java string)
env.set_object_array_element(&arguments, 0, env.new_string("--username").unwrap()).unwrap();
// JValue - This type is used for parameters passed to Java method calls.
// A reference JValueGen
// docs:
// https://docs.rs/jni/latest/jni/objects/enum.JValueGen.html#
// https://docs.rs/jni/latest/jni/objects/type.JValue.html
//
// &JObject::from(arguments) - create Java object instance from our arguments object array
//
env.call_static_method(class, main_method_name, main_signature, &[JValue::Object(&JObject::from(arguments))])
(Note: I've translated the code portion as requested.)
英文:
Finally. I solved the problem by spending a lot of time studying the documentation. Since I could not find information on the web (that's why I created the question), I'll leave the solution here.
To pass arguments to a method call, you need to do something like this:
// create Java array of objects (in our case, type string)
// 1 - one element of array
// stringClass - Java string class signature ("java/lang/String")
// env.new_string("") - initial element of array
let arguments: JObjectArray = env.new_object_array(1, stringClass, env.new_string("").unwrap()).unwrap();
// Set element at index 0
// &arguments - reference to our Java objects array
// 0 - element index (place at)
// env.new_string("--username") - the value we set at 0 index (create new java string)
env.set_object_array_element(&arguments, 0, env.new_string("--username").unwrap()).unwrap();
// JValue - This type is used for parameters passed to Java method calls.
// A reference JValueGen
// docs:
// https://docs.rs/jni/latest/jni/objects/enum.JValueGen.html#
// https://docs.rs/jni/latest/jni/objects/type.JValue.html
//
// &JObject::from(arguments) - create Java object instance from our arguments object array
//
env.call_static_method(class,main_method_name, main_signature, &[JValue::Object(&JObject::from(arguments))])
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论