JNI Rust如何传递参数以调用call_static_method?

huangapple go评论75阅读模式
英文:

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))])

huangapple
  • 本文由 发表于 2023年5月22日 23:46:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76307885.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定