• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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