Calling Rust
Exporting Rust functions and types to C is easy:
interoperability/rust/libanalyze/analyze.rs
1. ```
//! Rust FFI demo.
```
2. ```
#![deny(improper_ctypes_definitions)]
```
4. ```
use std::os::raw::c_int;
```
6. ```
/// Analyze the numbers.
```
7. ```
// SAFETY: There is no other global function of this name.
```
8. ```
#[unsafe(no_mangle)]
```
9. ```
pub extern "C" fn analyze_numbers(x: c_int, y: c_int) {
```
10. ```
if x < y {
```
11. ```
println!("x ({x}) is smallest!");
```
12. ```
} else {
```
13. ```
println!("y ({y}) is probably larger than x ({x})");
```
14. ```
}
```
15. ```
}
```
interoperability/rust/libanalyze/analyze.h
1. #ifndef ANALYSE_H
2. #define ANALYSE_H
4. void analyze_numbers(int x, int y);
6. #endif
interoperability/rust/libanalyze/Android.bp
1. rust_ffi {
2. name: "libanalyze_ffi",
3. crate_name: "analyze_ffi",
4. srcs: ["analyze.rs"],
5. include_dirs: ["."],
6. }
We can now call this from a C binary:
interoperability/rust/analyze/main.c
1. #include "analyze.h"
3. int main() {
4. analyze_numbers(10, 20);
5. analyze_numbers(123, 123);
6. return 0;
7. }
interoperability/rust/analyze/Android.bp
1. cc_binary {
2. name: "analyze_numbers",
3. srcs: ["main.c"],
4. static_libs: ["libanalyze_ffi"],
5. }
Build, push, and run the binary on your device:
1. m analyze_numbers
2. adb push "$ANDROID_PRODUCT_OUT/system/bin/analyze_numbers" /data/local/tmp
3. adb 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.
