使用 Bindgen

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

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

interoperability/bindgen/libbirthday.h:

1. typedef struct card {
2. const char* name;
3. int years;
4. } card;

6. void print_card(const card* card);

interoperability/bindgen/libbirthday.c:

1. #include <stdio.h>
2. #include "libbirthday.h"

4. void print_card(const card* card) {
5. printf("+--------------\n");
6. printf("| Happy Birthday %s!\n", card->name);
7. printf("| Congratulations with the %i years!\n", card->years);
8. printf("+--------------\n");
9. }

将该库添加到你的 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.

3. use birthday_bindgen::{card, print_card};

5. fn main() {
6. let name = std::ffi::CString::new("Peter").unwrap();
7. let card = card { name: name.as_ptr(), years: 42 };
8. // SAFETY: The pointer we pass is valid because it came from a Rust
9. // reference, and the `name` it contains refers to `name` above which also
10. // remains valid. `print_card` doesn't store either pointer to use later
11. // after it returns.
12. unsafe {
13. print_card(&card as *const card);
14. }
15. }

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

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