ブリッジモジュール

CXX は、各言語から他の言語に公開される関数シグネチャの記述に依存します。この記述は、#[cxx::bridge] 属性マクロでアノテーションされた Rust モジュール内の extern ブロックを使用して指定します。

#[allow(unsafe_op_in_unsafe_fn)]
#[cxx::bridge(namespace = "org::blobstore")]
mod ffi {
    // 両方の言語からアクセスできるフィールドを持つ共有構造体。
    struct BlobMetadata {
        size: usize,
        tags: Vec<String>,
    }

    // C++ に公開される Rust の型とシグネチャ。
    extern "Rust" {
        type MultiBuf;

        fn next_chunk(buf: &mut MultiBuf) -> &[u8];
    }

    // Rust に公開される C++ の型とシグネチャ。
    unsafe extern "C++" {
        include!("include/blobstore.h");

        type BlobstoreClient;

        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
        fn put(self: Pin<&mut BlobstoreClient>, parts: &mut MultiBuf) -> u64;
        fn tag(self: Pin<&mut BlobstoreClient>, blobid: u64, tag: &str);
        fn metadata(&self, blobid: u64) -> BlobMetadata;
    }
}
  • ブリッジは通常、クレート内の ffi モジュールで宣言します。
  • ブリッジ モジュールで行われた宣言から、CXX はマッチする Rust と C++ の型 / 関数の定義を生成し、これらのアイテムを両方の言語に公開します。
  • 生成された Rust コードを表示するには、cargo-expand を使用して、展開された proc マクロを表示します。ほとんどの例では、cargo expand ::ffi を使用して ffi モジュールのみを展開します(ただし、これは Android プロジェクトには当てはまりません)。
  • 生成された C++ コードを表示するには、target/cxxbridge を確認します。