Macro tao_macros::android_fn

source ·
android_fn!() { /* proc-macro */ }
Expand description

Generates a JNI binding for a Rust function so you can use it as the extern for Java/Kotlin class methods in your android app.

This macro expects 5 mandatory parameters and 3 optional:

  1. snake_case representation of the reversed domain of the app. for example: com_tao
  2. snake_case representation of the package name. for example: tao_app
  3. Java/Kotlin class name.
  4. Rust function name (ident).
  5. List of extra types your Rust function expects. Pass empty array if the function doesn’t need any arugments.
  • If your function takes an arguments as reference with a lifetime tied to the JNIEnv, it should use 'local as the lifetime name as it is the lifetime name generated by the macro. Note that all rust functions should expect the first two parameters to be JNIEnv and JClass so make sure they are imported into scope).
  1. (Optional) Return type of your rust function.
  • If your function returns a reference with a lifetime tied to the JNIEnv, it should use 'local as the lifetime name as it is the lifetime name generated by the macro.
  • if you want to use the next macro parameter you need to provide a type or just pass __VOID__ if the function doesn’t return anything.
  1. (Optional) List of idents to pass to the rust function when invoked (This mostly exists for internal usage by tao crate).
  2. (Optional) Function to be invoked right before invoking the rust function (This mostly exists for internal usage by tao crate).

§Example 1: Basic

android_fn![com_example, tao, OperationsClass, add, [i32, i32], i32];
unsafe fn add(_env: JNIEnv, _class: JClass, a: i32, b: i32) -> i32 {
  a + b
}

which will expand into:

#[no_mangle]
unsafe extern "C" fn Java_com_example_tao_OperationsClass_add<'local>(
  env: JNIEnv<'local>,
  class: JClass<'local>,
  a_1: i32,
  a_2: i32
)  -> i32 {
  add(env, class, a_1, a_2)
}

unsafe fn add<'local>(_env: JNIEnv<'local>, _class: JClass<'local>, a: i32, b: i32) -> i32 {
  a + b
}

and now you can extern the function in your Java/kotlin:

class OperationsClass {
  external fun add(a: Int, b: Int): Int;
}

§Example 2: Return a reference with a lifetime

android_fn![com_example, tao, OperationsClass, add, [JObject<'local>], JClass<'local>];
unsafe fn add<'local>(mut _env: JNIEnv<'local>, class: JClass<'local>, obj: JObject<'local>) -> JClass<'local> {
  class
}

which will expand into:

#[no_mangle]
unsafe extern "C" fn Java_com_example_tao_OperationsClass_add<'local>(
  env: JNIEnv<'local>,
  class: JClass<'local>,
  a_1: JObject<'local>,
)  -> JClass<'local> {
  add(env, class, a_1)
}

unsafe fn add<'local>(mut _env: JNIEnv<'local>, class: JClass<'local>, obj: JObject<'local>) -> JClass<'local> {
  class
}