#jni #java

jnino

Java Native Interface 到 rust 本地对象

2 个版本

0.1.1 2021 年 9 月 12 日
0.1.0 2021 年 9 月 7 日

#315 in FFI

MIT/Apache

6KB
54

该项目允许您像 JVM 对象的一部分一样使用 rust 对象。

JVM

  • 添加具有 Long 返回值和私有 Long 属性的本地构造函数

  • 以本地方法实现 AutoCloseable

  • 添加终结器

  • 添加本地方法

class Sample extends AutoCloseable {
  @native private def nnew(): Long
  @native def close: Unit
  @native def test: Unit
  private val ptr = nnew()
  override def finalize = close
}
  • 使用 try-with-resource (java) / Using (scala) 或隐式调用 close() (不要依赖最终化 — 它是一根薄红线)

Rust

  • 将结构标记为 JFace
#[derive(JFace)]
pub struct Sample {}
  • 使用 throw(JNIEnv, default_function) 将 rust Jr<_> (Result<_, Box>) 转换为默认 JVM 异常

  • 使用 JFace::jni() 转换为原始堆指针

  • 为 JNI 提供本地构造函数

#[no_mangle]
pub extern "system" fn Java_package_Sample_nnew(
  jenv: JNIEnv,
  _jclass: JClass,
) -> *mut Sample {
  Sample::new().jni().throw(jenv, null_mut)
}
  • 使用 unit for Result<(), _>::throw() 或 hide for Result<T, _>::throw 以隐藏不必要的 T

  • 使用 JFace::mut_raw 和 map/and_then 对本地方法

#[no_mangle]
pub extern "system" fn Java_org_apqm_jni_Sample_test(
  jenv: JNIEnv,
  jclass: JClass,
) {
  Sample::mut_raw(&jenv, jclass).map(|it| {
    todo!()
  }).throw(jenv, unit);
}
  • 使用 JFace::box_raw 作为析构函数
#[no_mangle]
pub extern "system" fn Java_org_apqm_jni_Sample_close(
  jenv: JNIEnv,
  jclass: JClass,
) {
  Sample::box_raw(&jenv, jclass).map(hide).throw(jenv, unit)
}

许可

许可协议为以下之一

依赖

~2.3–3.5MB
~65K SLoC