alef 0.23.39

Opinionated polyglot binding generator for Rust libraries
Documentation
#[unsafe(no_mangle)]
pub unsafe extern "system" fn {{ symbol }}(
    mut env: EnvUnowned,
    _class: JClass,
    impl_obj: JObject,
{% if not has_super_trait %}
    name: JString,
{% endif %}
) {
    // SAFETY: env is a valid EnvUnowned passed by the JVM for this native call frame.
    let mut __jni_attach_guard = unsafe { jni::AttachGuard::from_unowned(env.as_raw()) };
    let env = __jni_attach_guard.borrow_env_mut();
{% if has_super_trait %}
    let name = match jni_call_string_method(env, impl_obj, "name", "()Ljava/lang/String;") {
        Ok(n) => n,
        Err(e) => { throw_jni_error(env, &format!("Failed to get implementation name: {e}")); return; }
    };
{% else %}
    let name = match jstring_to_string(env, name) {
        Ok(s) => s,
        Err(e) => { throw_jni_error(env, &format!("Failed to decode name parameter: {e}")); return; }
    };
{% endif %}

    let global_impl = match env.new_global_ref(impl_obj) {
        Ok(g) => g,
        Err(e) => { throw_jni_error(env, &format!("Failed to create global reference: {e}")); return; }
    };

    let bridge_handle = std::sync::Arc::new(global_impl.clone());

    let Some(result) = run_or_throw(env, std::panic::AssertUnwindSafe(|| core_crate::{{ register_fn }}(&name, bridge_handle))) else {
        return;
    };
    if let Err(e) = result {
        // On registration failure, the global ref is cleaned up when bridge_handle is dropped
        throw_jni_error(env, &format!("{e}"));
    }
}