ماژول پل

‏ CXX متکی به توصیفی از signatureهای تابع است که از هر زبان به زبان دیگر در معرض دید قرار می‌گیرد. شما این توضیحات را با استفاده از بلوک‌های خارجی در یک ماژول Rust ارائه می‌کنید که با attribute ماکروها #[cxx::bridge] شرح داده شده است.

#[allow(unsafe_op_in_unsafe_fn)]
#[cxx::bridge(namespace = "org::blobstore")]
mod ffi {
    // Shared structs with fields visible to both languages.
    struct BlobMetadata {
        size: usize,
        tags: Vec<String>,
    }

    // Rust types and signatures exposed to C++.
    extern "Rust" {
        type MultiBuf;

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

    // C++ types and signatures exposed to Rust.
    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در crate شما اعلام می‌شود.
  • از اعلان‌های (declarations) انجام شده در ماژول پل، CXX تعاریف مطابق با type/function در Rust و ++C را ایجاد می‌کند تا آن موارد را در معرض هر دو زبان قرار دهد.
  • برای مشاهده کد Rust ایجاد شده از cargo-expand که برای مشاهده ماکرو proc توسعه یافته استفاده کنید. برای بیشتر نمونه‌ها از cargo expand ::ffi فقط برای گسترش ماژول ffi استفاده کنید (اگرچه این برای پروژه‌های Android کاربرد ندارد).
  • برای مشاهده کد ++C تولید شده به target/cxxbridge نگاه کنید.