Calling Rust
Exporting Rust functions and types to C is easy:
interoperability/rust/libanalyze/analyze.rs
//! Rust FFI demo.#![deny(improper_ctypes_definitions)]use std::os::raw::c_int;/// Analyze the numbers.// SAFETY: There is no other global function of this name.#[unsafe(no_mangle)]pub extern "C" fn analyze_numbers(x: c_int, y: c_int) {if x < y {println!("x ({x}) is smallest!");} else {println!("y ({y}) is probably larger than x ({x})");}}
interoperability/rust/libanalyze/analyze.h
#ifndef ANALYSE_H#define ANALYSE_Hvoid analyze_numbers(int x, int y);#endif
interoperability/rust/libanalyze/Android.bp
rust_ffi {name: "libanalyze_ffi",crate_name: "analyze_ffi",srcs: ["analyze.rs"],include_dirs: ["."],}
We can now call this from a C binary:
interoperability/rust/analyze/main.c
#include "analyze.h"int main() {analyze_numbers(10, 20);analyze_numbers(123, 123);return 0;}
interoperability/rust/analyze/Android.bp
cc_binary {name: "analyze_numbers",srcs: ["main.c"],static_libs: ["libanalyze_ffi"],}
Build, push, and run the binary on your device:
m analyze_numbersadb push "$ANDROID_PRODUCT_OUT/system/bin/analyze_numbers" /data/local/tmpadb shell /data/local/tmp/analyze_numbers
#[unsafe(no_mangle)] disables Rust’s usual name mangling, so the exported symbol will just be the name of the function. You can also use #[unsafe(export_name = "some_name")] to specify whatever name you want.