Code Monkey home page Code Monkey logo

rust-jni-demo's Introduction

Rust JNI Demo

使用Rust编写Java JNI库,Java已经非常🐂啦,为何还要用Rust来写一些代码?

  • WebAssembly支持方面Java还有一些问题,通过Rust可能更方便一些
  • Java还是不能访问一些底层的API,如SIMD,通过Rust性能提升可能非常明显
  • Rust也有非常强大的crates库 https://crates.io/ 自行选择
  • JEP 389: Foreign Linker API: https://openjdk.java.net/jeps/389

如何生成Rust JNI函数钩子

在Rust的lib.rs文件中,我们要实现JNI函数,那么这个函数的声明样式什么样的? 如函数名、签名等。

  • 首先我们根据Java类的 static native 函数生成对应的".h"文件,如下:
$ javac -h . src/main/java/org/mvnsearch/RustService.java
  • 在生成对应的".h"文件中,找到对应的声明函数,如:
JNIEXPORT jstring JNICALL Java_org_mvnsearch_RustService_hello
  (JNIEnv *, jclass, jstring);
  • 接下来在lib.rs添加对应的声明函数,然后实现其逻辑即可。
pub extern "system" fn Java_org_mvnsearch_RustService_hello(env: JNIEnv,
                                                            _class: JClass,
                                                            name: JString)
                                                            -> jstring {

考虑到时间测试的需要,个人建议是编写另外一个完全Rust Native的函数声明,然后Rust JNI函数钩子调用Rust Native函数,其目的主要是方便单元测试,如下:

fn hello(name: &str) -> String {
    format!("Hello {}!", name)
}

使用cross编译多平台的动态链接库

请参考mylib目录下的cross.sh脚本。

动态链接库加载目录

Java的System.load会从指定的目录加载,默认目录列表为System.getProperty("java.library.path"),你可以使用jshell查询,如下:

$ jshell
jshell> System.getProperty("java.library.path")
$1 ==> "~/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:."
jshell> /exit

然后将rust对应的开发包拷贝到上述之一目录就可以,如在我Mac笔记本下,命令如下:

$ cp -rf mylib/target/debug/libmylib.dylib ~/Library/Java/Extensions/

在测试的时候,我们可以通过设置java.library.path属性进行调整,只要指向Rust library的debug目录就可以,如下:

-Djava.library.path=/Users/xxxx/rust-jni-demo/mylib/target/debug

在IDE工具中,都有对应的VM options方便你进行设置。

Exception throw from Rust

fn java_string_with_exception(result: Result<String, ErrorMessages>, env: &JNIEnv) -> jstring {
    if let Ok(text) = result {
        env.new_string(text)
            .expect("Couldn't create java string!")
            .into_raw()
    } else {
        env.throw_new("java/lang/Exception", "something bad happened").unwrap();
        std::ptr::null_mut() as jstring
    }
}

References

rust-jni-demo's People

Contributors

linux-china avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.