From 139ee9fe6f283da6811e6a7dd3494c21e87d4070 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Thu, 30 Jan 2020 21:07:23 +0800 Subject: [PATCH] add jni --- jni/HelloWorld.java | 18 +++++++++++++++++ jni/README.md | 13 +++++++++++++ jni/samplejni/Cargo.toml | 11 +++++++++++ jni/samplejni/src/lib.rs | 42 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+) create mode 100644 jni/HelloWorld.java create mode 100644 jni/README.md create mode 100644 jni/samplejni/Cargo.toml create mode 100644 jni/samplejni/src/lib.rs diff --git a/jni/HelloWorld.java b/jni/HelloWorld.java new file mode 100644 index 0000000..9102bbe --- /dev/null +++ b/jni/HelloWorld.java @@ -0,0 +1,18 @@ +public class HelloWorld { + // This declares that the static `hello` method will be provided + // a native library. + private static native String hello(String input); + + static { + // This actually loads the shared object that we'll be creating. + // The actual location of the .so or .dll may differ based on your + // platform. + System.loadLibrary("samplejni"); + } + + // The rest is just regular ol' Java! + public static void main(String[] args) { + String output = HelloWorld.hello("josh"); + System.out.println(output); + } +} diff --git a/jni/README.md b/jni/README.md new file mode 100644 index 0000000..c46504a --- /dev/null +++ b/jni/README.md @@ -0,0 +1,13 @@ + +> https://docs.rs/jni/0.13.0/jni/ +> +> https://crates.io/crates/jni + +Run: +```bash +cd samplejni; cargo build +cd -; javac HelloWorld.java +LD_LIBRARY_PATH=samplejni/target/debug/ java HelloWorld +``` + + diff --git a/jni/samplejni/Cargo.toml b/jni/samplejni/Cargo.toml new file mode 100644 index 0000000..abe8d27 --- /dev/null +++ b/jni/samplejni/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "samplejni" +version = "0.1.0" +authors = ["Hatter Jiang@Pixelbook "] +edition = "2018" + +[dependencies] +jni = "0.13.0" + +[lib] +crate_type = ["cdylib"] diff --git a/jni/samplejni/src/lib.rs b/jni/samplejni/src/lib.rs new file mode 100644 index 0000000..d36a7b7 --- /dev/null +++ b/jni/samplejni/src/lib.rs @@ -0,0 +1,42 @@ +extern crate jni; + +// This is the interface to the JVM that we'll call the majority of our +// methods on. +use jni::JNIEnv; + +// These objects are what you should use as arguments to your native +// function. They carry extra lifetime information to prevent them escaping +// this context and getting used after being GC'd. +use jni::objects::{JClass, JString}; + +// This is just a pointer. We'll be returning it from our function. We +// can't return one of the objects with lifetime information because the +// lifetime checker won't let us. +use jni::sys::jstring; + +// This keeps Rust from "mangling" the name and making it unique for this +// crate. +#[no_mangle] +// This turns off linter warnings because the name doesn't conform to +// conventions. +#[allow(non_snake_case)] +pub extern "system" fn Java_HelloWorld_hello(env: JNIEnv, +// This is the class that owns our static method. It's not going to be used, +// but still must be present to match the expected signature of a static +// native method. + class: JClass, + input: JString) + -> jstring { + // First, we have to get the string out of Java. Check out the `strings` + // module for more info on how this works. + let input: String = + env.get_string(input).expect("Couldn't get java string!").into(); + + // Then we have to create a new Java string to return. Again, more info + // in the `strings` module. + let output = env.new_string(format!("Hello, {}!", input)) + .expect("Couldn't create java string!"); + + // Finally, extract the raw pointer to return. + output.into_inner() +} \ No newline at end of file