Using Bindgen

The bindgen tool can auto-generate bindings from a C header file.

First create a small C library:

interoperability/bindgen/libbirthday.h:

typedef struct card { const char* name; int years; } card; void print_card(const card* card);

interoperability/bindgen/libbirthday.c:

#include <stdio.h> #include "libbirthday.h" void print_card(const card* card) { printf("+--------------\n"); printf("| Happy Birthday %s!\n", card->name); printf("| Congratulations with the %i years!\n", card->years); printf("+--------------\n"); }

Add this to your Android.bp file:

interoperability/bindgen/Android.bp:

cc_library { name: "libbirthday", srcs: ["libbirthday.c"], }

Create a wrapper header file for the library (not strictly needed in this example):

interoperability/bindgen/libbirthday_wrapper.h:

#include "libbirthday.h"

You can now auto-generate the bindings:

interoperability/bindgen/Android.bp:

rust_bindgen { name: "libbirthday_bindgen", crate_name: "birthday_bindgen", wrapper_src: "libbirthday_wrapper.h", source_stem: "bindings", static_libs: ["libbirthday"], }

Finally, we can use the bindings in our Rust program:

interoperability/bindgen/Android.bp:

rust_binary { name: "print_birthday_card", srcs: ["main.rs"], rustlibs: ["libbirthday_bindgen"], }

interoperability/bindgen/main.rs:

  1. //! Bindgen demo.
  2. use birthday_bindgen::{card, print_card};
  3. fn main() {
  4. let name = std::ffi::CString::new("Peter").unwrap();
  5. let card = card {
  6. name: name.as_ptr(),
  7. years: 42,
  8. };
  9. unsafe {
  10. print_card(&card as *const card);
  11. }
  12. }

Build, push, and run the binary on your device:

$ m print_birthday_card $ adb push $ANDROID_PRODUCT_OUT/system/bin/print_birthday_card /data/local/tmp $ adb shell /data/local/tmp/print_birthday_card

Finally, we can run auto-generated tests to ensure the bindings work:

interoperability/bindgen/Android.bp:

rust_test { name: "libbirthday_bindgen_test", srcs: [":libbirthday_bindgen"], crate_name: "libbirthday_bindgen_test", test_suites: ["general-tests"], auto_gen_config: true, clippy_lints: "none", // Generated file, skip linting lints: "none", }

$ atest libbirthday_bindgen_test