バインディングの例

CXX では、C++ と Rust の境界全体を .rs ソースコード内の cxx::bridge モジュールで宣言する必要があります。

#[cxx::bridge]
mod ffi {
    extern "Rust" {
        type MultiBuf;

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

    unsafe extern "C++" {
        include!("example/include/blobstore.h");

        type BlobstoreClient;

        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
        fn put(self: &BlobstoreClient, buf: &mut MultiBuf) -> Result<u64>;
    }
}

// Rust の型と関数の定義をここに記述します。

以下を説明します。

  • これは通常の Rust mod のように見えますが、#[cxx::bridge] プロシージャル マクロはこれに対して複雑な処理を行います。生成されるコードはもっと洗練されていますが、それでもコードには ffi という mod が作成されます。
  • Rust での C++ の std::unique_ptr のネイティブ サポート
  • Native support for Rust slices in C++
  • C++ から Rust および Rust の型への呼び出し(上部)
  • Rust から C++ および C++ の型への呼び出し(下部)

よくある誤解: Rust で C++ ヘッダーが解析されているように見えますが、これは誤解です。このヘッダーは Rust では解釈されず、C++ コンパイラのために生成された C++ コードに #include されているだけです。