Usando Bindgen

A ferramenta bindgen pode gerar vínculos (bindings) automaticamente a partir de um arquivo de cabeçalho C.

Primeiro crie uma pequena biblioteca C:

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("|Feliz Aniversário %s!\n", card->name);
  printf("|Parabéns pelos %i anos!\n", card->years);
  printf("+--------------\n");
}

Adicione isto ao seu arquivo Android.bp:

interoperability/bindgen/Android.bp:

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

Crie um arquivo de cabeçalho wrapper para a biblioteca (não estritamente necessário neste exemplo):

interoperability/bindgen/libbirthday_wrapper.h:

#include "libbirthday.h"

Agora você pode gerar automaticamente as vinculações (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"],
}

Finalmente, podemos usar as vinculações (bindings) em nosso programa Rust:

interoperability/bindgen/Android.bp:

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

interoperability/bindgen/main.rs:

//! Bindgen demo.

use birthday_bindgen::{card, print_card};

fn main() {
    let name = std::ffi::CString::new("Peter").unwrap();
    let card = card { name: name.as_ptr(), years: 42 };
    // SEGURANÇA: O ponteiro que passamos é válido porque veio de uma referência Rust,
    // e o `name` que ele contém se refere a `name` acima, que também permanece
    // válido. `print_card` não armazena nenhum dos ponteiros para usar depois
    // que ele retorna.
    unsafe {
        print_card(&card as *const card);
    }
}

Compile, envie e execute o binário em seu dispositivo:

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

Por fim, podemos executar testes gerados automaticamente para garantir que as vinculações funcionem:

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", // Arquivo gerado, pule o linting
    lints: "none",
}
atest libbirthday_bindgen_test