C++ Bridge Declarations

  1. #[cxx::bridge]
  2. mod ffi {
  3. // C++ types and signatures exposed to Rust.
  4. unsafe extern "C++" {
  5. include!("include/blobstore.h");
  6. type BlobstoreClient;
  7. fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
  8. fn put(self: Pin<&mut BlobstoreClient>, parts: &mut MultiBuf) -> u64;
  9. fn tag(self: Pin<&mut BlobstoreClient>, blobid: u64, tag: &str);
  10. fn metadata(&self, blobid: u64) -> BlobMetadata;
  11. }
  12. }

Results in (roughly) the following Rust:

  1. #[repr(C)]
  2. pub struct BlobstoreClient {
  3. _private: ::cxx::private::Opaque,
  4. }
  5. pub fn new_blobstore_client() -> ::cxx::UniquePtr<BlobstoreClient> {
  6. extern "C" {
  7. #[link_name = "org$blobstore$cxxbridge1$new_blobstore_client"]
  8. fn __new_blobstore_client() -> *mut BlobstoreClient;
  9. }
  10. unsafe { ::cxx::UniquePtr::from_raw(__new_blobstore_client()) }
  11. }
  12. impl BlobstoreClient {
  13. pub fn put(&self, parts: &mut MultiBuf) -> u64 {
  14. extern "C" {
  15. #[link_name = "org$blobstore$cxxbridge1$BlobstoreClient$put"]
  16. fn __put(
  17. _: &BlobstoreClient,
  18. parts: *mut ::cxx::core::ffi::c_void,
  19. ) -> u64;
  20. }
  21. unsafe {
  22. __put(self, parts as *mut MultiBuf as *mut ::cxx::core::ffi::c_void)
  23. }
  24. }
  25. }
  26. // ...
  • The programmer does not need to promise that the signatures they have typed in are accurate. CXX performs static assertions that the signatures exactly correspond with what is declared in C++.
  • unsafe extern blocks allow you to declare C++ functions that are safe to call from Rust.