JNI:尝试在重写方法中调用本机方法时出现不明确的错误

问题描述 投票:0回答:1

我正在尝试创建一个实现 BiConsumer 并在被调用时调用函数指针的类。

我对此有以下部分:

实例化实现 BiConsumer 的类的 Rust 代码:

// 'mc is defined by the struct that holds this function
pub fn from_rust_fn(
    env: &JNIEnv<'mc>,
    f: &'static dyn Fn(jni::objects::JObject, jni::objects::JObject),
) -> Result<Self, Box<dyn Error>> {
    // Create the closure.
    let closure: &'static _ =
        Box::leak(Box::new(move |a: *mut _jobject, b: *mut _jobject| unsafe {
            f(
                jni::objects::JObject::from_raw(a),
                jni::objects::JObject::from_raw(b),
            );
        }));
    let callback = Closure2::new(closure);
    let &code = callback.code_ptr();
    let ptr: unsafe extern "C" fn(*const jobject) = unsafe { std::mem::transmute(code) };
    std::mem::forget(callback);

    // Create the java object.
    let obj = env.new_object(
        "net/ioixd/blackbox/BiConsumerLink",
        "(J)V",
        &[(ptr as i64).into()],
    );
    let obj = env.translate_error_no_gen(obj)?;

    Self::from_raw(env, obj)
}

实现BiConsumer的类的Java代码:

import java.util.function.BiConsumer;

public class BiConsumerLink implements BiConsumer {
    long address;

    BiConsumerLink(long address) {
        this.address = address;
    }

    public native void acceptNative(Object t, Object u);

    public void accept(Object t, Object u) {
        System.out.println((Object) t + "," + (Object) u);
        acceptNative((Object) t, (Object) u);
    }
}

以及链接到此类的另一段本机 Rust 代码:

type BiConsumer = unsafe extern "system" fn(t: JObject, u: JObject);
pub extern "system" fn Java_net_ioixd_blackbox_BiConsumerLink_acceptNative<'a>(
    mut env: JNIEnv<'a>,
    this: JObject,
    obj1: JObject,
    obj2: JObject,
) {
    || -> Result<(), Box<dyn Error>> {
        let address = env.get_field(this, "address", "long")?.i()? as u64;
        println!("{:#x}", address);
        unsafe {
            let func: BiConsumer = std::mem::transmute(address);
            func(obj1, obj2);
        }
        Ok(())
    }()
    .unwrap();
}

当从 JNI 调用 BiConsumer 的“本机”方法时,它会抛出一个仅包含函数签名的错误,而不会尝试执行 Rust 代码:

void net.ioixd.blackbox.BiConsumerLink.acceptNative(java.lang.Object, java.lang.Object)

通常当 jni-rs 抛出此错误时,它表明我得到的函数签名错误。但在这种情况下,我已经检查了三次,这就是我应该得到的。我留下的假设是,这是我尝试通过覆盖方法执行此操作的结果。

java rust java-native-interface
1个回答
0
投票

我忘了在函数上方添加

[#no_mangle]

© www.soinside.com 2019 - 2024. All rights reserved.