• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1{{#title extern "Rust" — Rust ♡ C++}}
2# extern "Rust"
3
4```rust,noplayground
5#[cxx::bridge]
6mod ffi {
7    extern "Rust" {
8
9    }
10}
11```
12
13The `extern "Rust"` section of a CXX bridge declares Rust types and signatures
14to be made available to C++.
15
16The CXX code generator uses your extern "Rust" section(s) to produce a C++
17header file containing the corresponding C++ declarations. The generated header
18has the same path as the Rust source file containing the bridge, except with a
19`.rs.h` file extension.
20
21A bridge module may contain zero or more extern "Rust" blocks.
22
23## Opaque Rust types
24
25Types defined in Rust that are made available to C++, but only behind an
26indirection.
27
28```rust,noplayground
29# #[cxx::bridge]
30# mod ffi {
31    extern "Rust" {
32        type MyType;
33        type MyOtherType;
34        type OneMoreType<'a>;
35    }
36# }
37```
38
39For example in the ***[Tutorial](tutorial.md)*** we saw `MultiBuf` used in this
40way. Rust code created the `MultiBuf`, passed a `&mut MultiBuf` to C++, and C++
41later passed a `&mut MultiBuf` back across the bridge to Rust.
42
43Another example is the one on the ***[Box\<T\>](binding/box.md)*** page, which
44exposes the Rust standard library's `std::fs::File` to C++ as an opaque type in
45a similar way but with Box as the indirection rather than &mut.
46
47The types named as opaque types (`MyType` etc) refer to types in the `super`
48module, the parent module of the CXX bridge. You can think of an opaque type `T`
49as being like a re-export `use super::T` made available to C++ via the generated
50header.
51
52Opaque types are currently required to be [`Sized`] and [`Unpin`]. In
53particular, a trait object `dyn MyTrait` or slice `[T]` may not be used for an
54opaque Rust type. These restrictions may be lifted in the future.
55
56[`Sized`]: https://doc.rust-lang.org/std/marker/trait.Sized.html
57[`Unpin`]: https://doc.rust-lang.org/std/marker/trait.Unpin.html
58
59For now, types used as extern Rust types are required to be defined by the same
60crate that contains the bridge using them. This restriction may be lifted in the
61future.
62
63The bridge's parent module will contain the appropriate imports or definitions
64for these types.
65
66```rust,noplayground
67use path::to::MyType;
68
69pub struct MyOtherType {
70    ...
71}
72#
73# #[cxx::bridge]
74# mod ffi {
75#     extern "Rust" {
76#         type MyType;
77#         type MyOtherType;
78#     }
79# }
80```
81
82## Functions
83
84Rust functions made callable to C++.
85
86Just like for opaque types, these functions refer implicitly to something in
87scope in the `super` module, whether defined there or imported by some `use`
88statement.
89
90```rust,noplayground
91#[cxx::bridge]
92mod ffi {
93    extern "Rust" {
94        struct MyType;
95        fn f() -> Box<MyType>;
96    }
97}
98
99struct MyType(i32);
100
101fn f() -> Box<MyType> {
102    return Box::new(MyType(1));
103}
104```
105
106Extern Rust function signature may consist of types defined in the bridge,
107primitives, and [any of these additional bindings](bindings.md).
108
109## Methods
110
111Any signature with a `self` parameter is interpreted as a Rust method and
112exposed to C++ as a non-static member function.
113
114```rust,noplayground
115# #[cxx::bridge]
116# mod ffi {
117    extern "Rust" {
118        type MyType;
119        fn f(&self) -> usize;
120    }
121# }
122```
123
124The `self` parameter may be a shared reference `&self`, an exclusive reference
125`&mut self`, or a pinned reference `self: Pin<&mut Self>`. A by-value `self` is
126not currently supported.
127
128If the surrounding `extern "Rust"` block contains exactly one extern type, that
129type is implicitly the receiver for a `&self` or `&mut self` method. If the
130surrounding block contains *more than one* extern type, a receiver type must be
131provided explicitly for the self parameter, or you can consider splitting into
132multiple extern blocks.
133
134```rust,noplayground
135# #[cxx::bridge]
136# mod ffi {
137    extern "Rust" {
138        type First;
139        type Second;
140        fn bar(self: &First);
141        fn foo(self: &mut Second);
142    }
143# }
144```
145
146## Functions with explicit lifetimes
147
148An extern Rust function signature is allowed to contain explicit lifetimes but
149in this case the function must be declared unsafe-to-call. This is pretty
150meaningless given we're talking about calls from C++, but at least it draws some
151extra attention from the caller that they may be responsible for upholding some
152atypical lifetime relationship.
153
154```rust,noplayground
155#[cxx::bridge]
156mod ffi {
157    extern "Rust" {
158        type MyType;
159        unsafe fn f<'a>(&'a self, s: &str) -> &'a str;
160    }
161}
162```
163
164Bounds on a lifetime (like `<'a, 'b: 'a>`) are not currently supported. Nor are
165type parameters or where-clauses.
166