Модуль Bridge
CXX покладається на опис сигнатур функцій, які будуть передаватися з однієї мови до іншої. Ви надаєте цей опис за допомогою блоків extern у модулі Rust, анотованому макросом з атрибутом #[cxx::bridge]
.
#[allow(unsafe_op_in_unsafe_fn)]
#[cxx::bridge(namespace = "org::blobstore")]
mod ffi {
// Спільні структури з полями, видимими для обох мов.
struct BlobMetadata {
size: usize,
tags: Vec<String>,
}
// Типи та сигнатури Rust, що доступні у C++.
extern "Rust" {
type MultiBuf;
fn next_chunk(buf: &mut MultiBuf) -> &[u8];
}
// Типи та сигнатури C++, доступні у 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
у вашому крейті. - На основі оголошень, зроблених у модулі-містку, CXX згенерує відповідні визначення типів/функцій Rust та C++, щоб зробити ці елементи доступними для обох мов.
- Щоб переглянути згенерований код Rust, скористайтеся cargo-expand для перегляду розширеного макросу proc. У більшості прикладів ви можете використовувати
cargo expand ::ffi
для розгортання лише модуляffi
(хоча це не стосується проектів для Android). - Щоб переглянути згенерований C++ код, подивіться у
target/cxxbridge
.