Modul Bindgen Binding

Sistem build mendukung pembuatan binding bindgen melalui tipe modul rust_bindgen . Bindgen menyediakan binding FFI Rust ke pustaka C (dengan beberapa dukungan C++ terbatas, yang memerlukan pengaturan properti cppstd ).

Penggunaan rust_bindgen dasar

Berikut ini adalah contoh bagaimana mendefinisikan modul yang menggunakan bindgen, dan bagaimana menggunakan modul itu sebagai peti. Jika Anda perlu menggunakan binding bindgen melalui makro include!() , seperti untuk kode eksternal, lihat halaman Generator Sumber .

Contoh library C untuk dipanggil dari Rust

Contoh library C yang mendefinisikan struct dan fungsi untuk digunakan di Rust berikut.

external/rust/libbuzz/libbuzz.h

typedef struct foo {
    int x;
} foo;

void fizz(int i, foo* cs);

external/rust/libbuzz/libbuzz.c

#include <stdio.h>
#include "libbuzz.h"

void fizz(int i, foo* my_foo){
    printf("hello from c! i = %i, my_foo->x = %i\n", i, my_foo->x);
}

Mendefinisikan modul rust_bindgen

Tentukan header pembungkus, external/rust/libbuzz/libbuzz_wrapper.h , yang mencakup semua header yang relevan:

// Include headers that are required for generating bindings in a wrapper header.
#include "libbuzz.h"

Tentukan file Android.bp sebagai external/rust/libbuzz/Android.bp :

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

rust_bindgen {
     name: "libbuzz_bindgen",

     // Crate name that's used to generate the rust_library variants.
     crate_name: "buzz_bindgen",

     // Path to the wrapper source file.
     wrapper_src: "libbuzz_wrapper.h",

     // 'source_stem' controls the output filename.
     // This is the filename that's used in an include! macro.
     //
     // In this case, we just use "bindings", which produces
     // "bindings.rs".
     source_stem: "bindings",

     // Bindgen-specific flags and options to customize the bindings.
     // See the bindgen manual for more information.
     bindgen_flags: ["--verbose"],

     // Clang flags to be used when generating the bindings.
     cflags: ["-DSOME_FLAG"],

     // Shared, static, and header libraries which export the necessary
     // include directories must be specified.
     //
     // These libraries will also be included in the crate if static,
     // or propagated to dependents if shared.
     // static_libs: ["libbuzz"]
     // header_libs: ["libbuzz"]
     shared_libs: ["libbuzz"],
}

Untuk mempelajari lebih lanjut tentang menggunakan flag bindgen, lihat bagian manual bindgen tentang Menyesuaikan Binding yang Dihasilkan .

Jika Anda menggunakan bagian ini untuk mendefinisikan modul rust_bindgen sebagai prasyarat untuk menggunakan makro include!() , kembali ke Prasyarat pada halaman Generator Sumber. Jika tidak, lanjutkan dengan bagian berikutnya.

Menggunakan binding sebagai peti

Buat external/rust/hello_bindgen/Android.bp dengan konten berikut:

rust_binary {
   name: "hello_bindgen",
   srcs: ["main.rs"],

   // Add the rust_bindgen module as if it were a rust_library dependency.
   rustlibs: ["libbuzz_bindgen"],
}

Buat external/rust/hello_bindgen/src/main.rs dengan konten berikut:

//! Example crate for testing bindgen bindings

fn main() {
    let mut x = buzz_bindgen::foo { x: 2 };
    unsafe { buzz_bindgen::fizz(1, &mut x as *mut buzz_bindgen::foo) }
}

Terakhir, panggil m hello_bindgen untuk membangun biner.

Menguji pengikatan Bindgen

Bindgen binding biasanya berisi sejumlah tes tata letak yang dihasilkan untuk mencegah ketidakcocokan tata letak memori. AOSP merekomendasikan agar Anda memiliki modul pengujian yang ditentukan untuk pengujian ini, dan pengujian tersebut dijalankan sebagai bagian dari rangkaian pengujian normal proyek Anda.

Biner uji untuk ini dapat dengan mudah dibuat dengan mendefinisikan modul rust_test di external/rust/hello_bindgen/Android.bp :

rust_test {
    name: "bindings_test",
    srcs: [
        ":libbuzz_bindgen",
    ],
    crate_name: "buzz_bindings_test",
    test_suites: ["general-tests"],
    auto_gen_config: true,

    // Be sure to disable lints as the generated source
    // is not guaranteed to be lint-free.
    clippy_lints: "none",
    lints: "none",
}

Properti rust_bindgen yang terkenal

Properti yang ditentukan di bawah ini adalah tambahan dari Properti umum penting yang berlaku untuk semua modul. Ini sangat penting untuk modul Rust bindgen, atau menunjukkan perilaku unik khusus untuk tipe modul rust_bindgen .

batang, nama, peti_nama

rust_bindgen menghasilkan varian library, sehingga memiliki persyaratan yang sama dengan modul rust_library untuk properti stem , name , dan crate_name . Lihat properti perpustakaan Karat Terkemuka untuk referensi.

pembungkus_src

Ini adalah jalur relatif ke file header pembungkus yang menyertakan header yang diperlukan untuk binding ini. Ekstensi file menentukan cara menginterpretasikan header dan menentukan flag -std mana yang akan digunakan secara default. Ini dianggap sebagai header C kecuali ekstensinya adalah .hh atau .hpp . Jika header C++ Anda harus memiliki beberapa ekstensi lain, setel properti cpp_std untuk menimpa perilaku default yang menganggap file tersebut adalah file C.

source_stem

Ini adalah nama file untuk file sumber yang dihasilkan . Bidang ini harus ditentukan, bahkan jika Anda menggunakan binding sebagai peti, karena properti stem hanya mengontrol nama file keluaran untuk varian pustaka yang dihasilkan. Jika sebuah modul bergantung pada beberapa generator sumber (seperti bindgen dan protobuf ) sebagai sumber daripada sebagai peti melalui rustlibs , Anda harus memastikan bahwa semua generator sumber yang merupakan dependensi modul tersebut memiliki nilai source_stem yang unik. Modul dependen menyalin sumber dari semua dependensi SourceProvider yang didefinisikan dalam srcs ke direktori OUT_DIR umum, jadi tabrakan di source_stem akan mengakibatkan file sumber yang dihasilkan ditimpa di direktori OUT_DIR .

c_std

Ini adalah string yang mewakili versi standar-C mana yang akan digunakan. Nilai yang valid tercantum di bawah ini:

  • Versi tertentu, seperti "gnu11"
    • Nilai "eksperimental" yang ditentukan oleh sistem build di build/soong/cc/config/global.go , dapat menggunakan versi draf seperti C++1z jika tersedia.
    • "default" atau " " keduanya menggunakan sistem build default.

Jika ini disetel, ekstensi file diabaikan dan header dianggap sebagai header C. Ini tidak dapat disetel bersamaan dengan cpp_std .

cpp_std

cpp_std adalah string yang mewakili versi standar C mana yang akan digunakan. Nilai yang valid:

  • Versi tertentu, seperti "gnu++11"

    • Nilai "eksperimental" yang ditentukan oleh sistem build di build/soong/cc/config/global.go , dapat menggunakan versi draf seperti C++1z jika tersedia.
    • "default" atau " " keduanya merupakan sistem build default.

Jika ini disetel, ekstensi file akan diabaikan dan header dianggap sebagai header C++. Ini tidak dapat disetel bersamaan dengan c_std .

cflag

cflags menyediakan daftar string flag Clang yang diperlukan untuk menginterpretasikan header dengan benar.

custom_bindgen

Untuk kasus penggunaan tingkat lanjut, bindgen dapat digunakan sebagai pustaka, menyediakan API yang dapat dimanipulasi sebagai bagian dari biner Rust kustom. Bidang custom_bindgen mengambil nama modul dari modul rust_binary_host , yang menggunakan API bindgen alih-alih biner bindgen normal.

Biner khusus ini harus mengharapkan argumen dengan cara yang mirip dengan bindgen , seperti " my_bindgen [flags] wrapper_header.h -o [output\_path] -- [clang flags] ". Sebagian besar ini ditangani oleh perpustakaan bindgen itu sendiri. Untuk melihat contoh penggunaan ini, kunjungi external/rust/crates/libsqlite3-sys/android/build.rs .

Selain itu, set lengkap properti pustaka tersedia untuk mengontrol kompilasi pustaka, meskipun ini jarang perlu didefinisikan atau diubah.