使用 Bindgen

bindgen 工具可以自动生成 C 头文件的绑定代码。

首先创建一个小型的 C 语言库:

interoperability/bindgen/libbirthday.h:

  1. typedef struct card {
  2. const char* name;
  3. int years;
  4. } card;
  5. void print_card(const card* card);

interoperability/bindgen/libbirthday.c:

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

将该库添加到你的 Android.bp 文件中:

interoperability/bindgen/Android.bp:

  1. cc_library {
  2. name: "libbirthday",
  3. srcs: ["libbirthday.c"],
  4. }

为该库创建一个包装头文件(在此示例中不是必需的):

interoperability/bindgen/libbirthday_wrapper.h:

  1. #include "libbirthday.h"

您现在可以自动生成绑定代码:

interoperability/bindgen/Android.bp:

  1. rust_bindgen {
  2. name: "libbirthday_bindgen",
  3. crate_name: "birthday_bindgen",
  4. wrapper_src: "libbirthday_wrapper.h",
  5. source_stem: "bindings",
  6. static_libs: ["libbirthday"],
  7. }

最后,我们可以在 Rust 程序中使用这些绑定:

interoperability/bindgen/Android.bp:

  1. rust_binary {
  2. name: "print_birthday_card",
  3. srcs: ["main.rs"],
  4. rustlibs: ["libbirthday_bindgen"],
  5. }

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 { name: name.as_ptr(), years: 42 };
  6. // SAFETY: The pointer we pass is valid because it came from a Rust
  7. // reference, and the `name` it contains refers to `name` above which also
  8. // remains valid. `print_card` doesn't store either pointer to use later
  9. // after it returns.
  10. unsafe {
  11. print_card(&card as *const card);
  12. }
  13. }

在你的设备上构建,推送,并运行二进制文件 :

  1. m print_birthday_card
  2. adb push "$ANDROID_PRODUCT_OUT/system/bin/print_birthday_card" /data/local/tmp
  3. adb shell /data/local/tmp/print_birthday_card

最后,我们可以运行自动生成的测试来确保绑定代码正常工作:

interoperability/bindgen/Android.bp:

  1. rust_test {
  2. name: "libbirthday_bindgen_test",
  3. srcs: [":libbirthday_bindgen"],
  4. crate_name: "libbirthday_bindgen_test",
  5. test_suites: ["general-tests"],
  6. auto_gen_config: true,
  7. clippy_lints: "none", // Generated file, skip linting
  8. lints: "none",
  9. }
  1. atest libbirthday_bindgen_test