java 与 rust jni

新建 Java Class

编写 java class
package com.example;

public class WASMContainer {

    private static native String hello();

    private static native String handle(String request, WASMContainer context);

    static {
        System.loadLibrary("wasmlib");
    }

    public static void main(String[] args) {
        // example 1
        String helloMessage = WASMContainer.hello();
        System.out.println(helloMessage);

        String response = WASMContainer.handle("reqeust", new WASMContainer());
        System.out.println(" response =>  " + response);
    }

    public String invoke(String request) {
        return " " + request + " invoke_result ";
    }
}
生成函数签名
$ javac -h . ./com/example/WASMContainer.java

# 如果需要相关 jar 包的情况
$ javac -h . -cp .:/path/to/jar ./com/example/WASMContainer.java
查看相关 header 文件,可获知:
/*
 * Class:     com_example_WASMContainer
 * Method:    hello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_WASMContainer_hello
  (JNIEnv *, jclass);

/*
 * Class:     com_example_WASMContainer
 * Method:    handle
 * Signature: (Ljava/lang/String;Lcom/example/WASMContainer;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_WASMContainer_handle
  (JNIEnv *, jclass, jstring, jobject);

实现 JNI 函数

初始化

$ cargo new wasmlib --lib

# 进入 wasmlib 目录
$ cd wasmlib

# 添加依赖
$ cargo add jni

# 添加目标为 c dynamic library
$ cat >> ./Cargo.toml << "EOF"

[lib]
crate_type = ["cdylib"]

EOF

代码

参考 https://docs.rs/jni/latest/jni/

#[no_mangle]
pub extern "system" fn Java_com_example_WASMContainer_hello<'local>(
    mut env: JNIEnv<'local>,
    class: JClass<'local>,
    input: JString<'local>,
) -> JString<'local> {

    let output = env.new_string("OK").expect("can't create string");
    output

}

构建

$ cargo build

# 按需构建指定目标架构
$ rustup target add x86_64-apple-darwin
$ cargo build --target x86_64-apple-darwin
构建产物在 `target/debug/libwasmlib.dylib`,不同操作系统会有不同的名称,比如:`.so`, `.dll` 等。

java - jni 运行

$ cd ./java-container
$ java -Djava.library.path=../wasmlib/target/debug  com.example.WASMContainer
OK
 response =>   final_result reqeust from_wasm invoke_result

References