如何使用从 rust Vec 中提取的参数列表调用可变参数 C 函数?



我正在尝试从 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>以便为CallStaticVoidMethodJNI 函数提供最终参数?

你可以用正常的方式从 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 文档

相关内容

  • 没有找到相关文章

最新更新