El Modulo Puente (Bridge)
CXX se basa en una descripción de las firmas de la función que se mostrarán de un lenguaje a otro. Proporcionas esta descripción mediante bloques externos en un módulo de Rust anotado con la macro de atributo #[cxx::bridge]
.
#[allow(unsafe_op_in_unsafe_fn)]
#[cxx::bridge(namespace = "org::blobstore")]
mod ffi {
// Estructuras compartidas con campos visibles para ambos lenguajes.
struct BlobMetadata {
size: usize,
tags: Vec<String>,
}
// Tipos y firmas de Rust expuestos a C++.
extern "Rust" {
type MultiBuf;
fn next_chunk(buf: &mut MultiBuf) -> &[u8];
}
// Tipos y firmas de C++ y expuestos a 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;
}
}
- Bridge se declara generalmente en un módulo
ffi
dentro del crate. - A partir de las declaraciones que se han hecho en el módulo bridge, CXX generará definiciones de funciones o tipos de Rust y C++ que coincidan para exponer esos elementos a ambos lenguajes.
- Para ver el código de Rust generado, usa cargo-expand para ver la macro de procedimiento desplegada. En la mayoría de los ejemplos, se utilizaría
cargo expand ::ffi
para desplegar únicamente el móduloffi
(aunque esta acción no se aplica a los proyectos de Android). - Para ver el código C++ generado, consulta
target/cxxbridge
.