Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Модуль bridge

CXX опирается на описание сигнатур функций, которые будут открыты с каждой стороны для другой. Вы задаёте это описание с помощью блоков extern в модуле Rust, помеченном атрибутным макросом #[cxx::bridge].

// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0

#[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, чтобы увидеть раскрытый процедурный макрос. Для большинства примеров можно использовать cargo expand ::ffi, чтобы раскрыть только модуль ffi (однако это не относится к проектам Android).
  • Чтобы посмотреть сгенерированный код C++, загляните в target/cxxbridge.