1{{#title Core concepts — Rust ♡ C++}} 2# Core concepts 3 4This page is a brief overview of the major concepts of CXX, enough so that you 5recognize the shape of things as you read the tutorial and following chapters. 6 7In CXX, the language of the FFI boundary involves 3 kinds of items: 8 9- **Shared structs** — data structures whose fields are made visible to 10 both languages. The definition written within cxx::bridge in Rust is usually 11 the single source of truth, though there are ways to do sharing based on a 12 bindgen-generated definition with C++ as source of truth. 13 14- **Opaque types** — their fields are secret from the other language. 15 These cannot be passed across the FFI by value but only behind an indirection, 16 such as a reference `&`, a Rust `Box`, or a C++ `unique_ptr`. Can be a type 17 alias for an arbitrarily complicated generic language-specific type depending 18 on your use case. 19 20- **Functions** — implemented in either language, callable from the other 21 language. 22 23```rust,noplayground,focuscomment 24# #[cxx::bridge] 25# mod ffi { 26 // Any shared structs, whose fields will be visible to both languages. 27# struct BlobMetadata { 28# size: usize, 29# tags: Vec<String>, 30# } 31# 32# extern "Rust" { 33 // Zero or more opaque types which both languages can pass around 34 // but only Rust can see the fields. 35# type MultiBuf; 36# 37 // Functions implemented in Rust. 38# fn next_chunk(buf: &mut MultiBuf) -> &[u8]; 39# } 40# 41# unsafe extern "C++" { 42 // One or more headers with the matching C++ declarations for the 43 // enclosing extern "C++" block. Our code generators don't read it 44 // but it gets #include'd and used in static assertions to ensure 45 // our picture of the FFI boundary is accurate. 46# include!("demo/include/blobstore.h"); 47# 48 // Zero or more opaque types which both languages can pass around 49 // but only C++ can see the fields. 50# type BlobstoreClient; 51# 52 // Functions implemented in C++. 53# fn new_blobstore_client() -> UniquePtr<BlobstoreClient>; 54# fn put(&self, parts: &mut MultiBuf) -> u64; 55# fn tag(&self, blobid: u64, tag: &str); 56# fn metadata(&self, blobid: u64) -> BlobMetadata; 57# } 58# } 59``` 60 61Within the `extern "Rust"` part of the CXX bridge we list the types and 62functions for which Rust is the source of truth. These all implicitly refer to 63the `super` module, the parent module of the CXX bridge. You can think of the 64two items listed in the example above as being like `use super::MultiBuf` and 65`use super::next_chunk` except re-exported to C++. The parent module will either 66contain the definitions directly for simple things, or contain the relevant 67`use` statements to bring them into scope from elsewhere. 68 69Within the `extern "C++"` part, we list types and functions for which C++ is the 70source of truth, as well as the header(s) that declare those APIs. In the future 71it's possible that this section could be generated bindgen-style from the 72headers but for now we need the signatures written out; static assertions verify 73that they are accurate. 74 75<br><br> 76 77Be aware that the design of this library is intentionally restrictive and 78opinionated! It isn't a goal to be flexible enough to handle an arbitrary 79signature in either language. Instead this project is about carving out a highly 80expressive set of functionality about which we can make powerful safety 81guarantees today and extend over time. You may find that it takes some practice 82to use CXX bridge effectively as it won't work in all the ways that you may be 83used to. 84 85<br> 86