如何使用从 rust Vec 中提取的参数列表调用可变参数 C 函数?
How can I call a variadic C function with a list of arguments pulled from a rust Vec?
我正在尝试从 Rust 调用 JNI 函数 CallStaticVoidMethod
。 jni-sys 包装器将其声明为
pub CallStaticVoidMethod:
Option<unsafe extern "C" fn(env: *mut JNIEnv, cls: jclass, methodID: jmethodID, ...)>,
我想用更安全的方式包装这个调用,所以我在我的包装对象上创建了这个方法:
pub fn call_static_void_method(&mut self, cls: jclass, method: jmethod, args: & Vec<jobject>)
{
let csvm;
unsafe {
csvm = (**self.env_ptr).CallStaticVoidMethod.expect("no implementation of CallStaticVoidMethod");
}
unsafe {
return csvm(self.env_ptr, cls, method, /*what here?*/);
}
}
如何转换 args:Vec<jobject>
以便我可以为 CallStaticVoidMethod
JNI 函数提供最终参数?
您可以以正常方式从 Rust 调用可变参数 C 函数,但是使用仅在运行时已知的参数列表调用它们是另一回事。据我了解,在 C 中甚至不可能(至少不是以符合标准的方式)。
幸运的是,您似乎不需要这样做。 JNI 提供了另一种方法,CallStaticVoidMethodA
,定义为:
NativeType CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
其中 args
指向包含参数的数组,格式为 jvalue
。
您正在收到 Vec<jobject>
; jvalue
是各种值的联合,因此您需要将 Vec<jobject>
转换为 jvalue
的数组。或者,如果您的函数可以接受 Vec<jvalue>
会更灵活,因为您将能够调用接受各种参数类型的方法——在这种情况下,您可以像这样传递 args.as_ptr()
:
pub fn call_static_void_method(&mut self, cls: jclass, method: jmethod, args: & Vec<jvalue>)
{
let csvm;
unsafe {
csvm = (**self.env_ptr).CallStaticVoidMethodA.expect("no implementation of CallStaticVoidMethodA");
}
unsafe {
return csvm(self.env_ptr, cls, method, args.as_ptr());
}
}
所有用于调用方法的 JNI 函数都有此主题的变体。
另请参阅:JNI Documentation
我正在尝试从 Rust 调用 JNI 函数 CallStaticVoidMethod
。 jni-sys 包装器将其声明为
pub CallStaticVoidMethod:
Option<unsafe extern "C" fn(env: *mut JNIEnv, cls: jclass, methodID: jmethodID, ...)>,
我想用更安全的方式包装这个调用,所以我在我的包装对象上创建了这个方法:
pub fn call_static_void_method(&mut self, cls: jclass, method: jmethod, args: & Vec<jobject>)
{
let csvm;
unsafe {
csvm = (**self.env_ptr).CallStaticVoidMethod.expect("no implementation of CallStaticVoidMethod");
}
unsafe {
return csvm(self.env_ptr, cls, method, /*what here?*/);
}
}
如何转换 args:Vec<jobject>
以便我可以为 CallStaticVoidMethod
JNI 函数提供最终参数?
您可以以正常方式从 Rust 调用可变参数 C 函数,但是使用仅在运行时已知的参数列表调用它们是另一回事。据我了解,在 C 中甚至不可能(至少不是以符合标准的方式)。
幸运的是,您似乎不需要这样做。 JNI 提供了另一种方法,CallStaticVoidMethodA
,定义为:
NativeType CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args);
其中 args
指向包含参数的数组,格式为 jvalue
。
您正在收到 Vec<jobject>
; jvalue
是各种值的联合,因此您需要将 Vec<jobject>
转换为 jvalue
的数组。或者,如果您的函数可以接受 Vec<jvalue>
会更灵活,因为您将能够调用接受各种参数类型的方法——在这种情况下,您可以像这样传递 args.as_ptr()
:
pub fn call_static_void_method(&mut self, cls: jclass, method: jmethod, args: & Vec<jvalue>)
{
let csvm;
unsafe {
csvm = (**self.env_ptr).CallStaticVoidMethodA.expect("no implementation of CallStaticVoidMethodA");
}
unsafe {
return csvm(self.env_ptr, cls, method, args.as_ptr());
}
}
所有用于调用方法的 JNI 函数都有此主题的变体。
另请参阅:JNI Documentation