C++ ๋ธŒ๋ฆฌ์ง€ ์„ ์–ธ

#[cxx::bridge]
mod ffi {
    // Rust์— ๋…ธ์ถœ๋œ C++ ํƒ€์ž… ๋ฐ ํ•จ์ˆ˜ ์‹œ๊ทธ๋‹ˆ์ณ์ž…๋‹ˆ๋‹ค.
    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;
    }
}

๊ฒฐ๊ณผ๋Š” ๋Œ€๋žต ๋‹ค์Œ๊ณผ ๊ฐ™์€ Rust์ž…๋‹ˆ๋‹ค.

#[repr(C)]
pub struct BlobstoreClient {
    _private: ::cxx::private::Opaque,
}

pub fn new_blobstore_client() -> ::cxx::UniquePtr<BlobstoreClient> {
    extern "C" {
        #[link_name = "org$blobstore$cxxbridge1$new_blobstore_client"]
        fn __new_blobstore_client() -> *mut BlobstoreClient;
    }
    unsafe { ::cxx::UniquePtr::from_raw(__new_blobstore_client()) }
}

impl BlobstoreClient {
    pub fn put(&self, parts: &mut MultiBuf) -> u64 {
        extern "C" {
            #[link_name = "org$blobstore$cxxbridge1$BlobstoreClient$put"]
            fn __put(
                _: &BlobstoreClient,
                parts: *mut ::cxx::core::ffi::c_void,
            ) -> u64;
        }
        unsafe {
            __put(self, parts as *mut MultiBuf as *mut ::cxx::core::ffi::c_void)
        }
    }
}

// ...
  • ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์ž์‹ ์ด ์ž…๋ ฅํ•œ ์‹œ๊ทธ๋‹ˆ์ณ๊ฐ€ ์ •ํ™•ํ•˜๋‹ค๊ณ  ๋ณด์žฅํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. CXX๋Š” ์‹œ๊ทธ๋‹ˆ์ณ๊ฐ€C++์—์„œ ์„ ์–ธ๋œ ๊ฒƒ๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•˜๋Š”์ง€๋ฅผ ์ฒดํฌํ•˜๊ธฐ ์œ„ํ•ด ์ •์ ์œผ๋กœ assertion์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • unsafe extern ๋ธ”๋ก์„ ์‚ฌ์šฉํ•˜๋ฉด Rust์—์„œ ์•ˆ์ „ํ•˜๊ฒŒ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” C++ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.