2023-11-27 18:21:19 +00:00
|
|
|
# Exercise: Interoperability with C++
|
|
|
|
|
|
|
|
## Part one
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
- In the Rust file you previously created, add a `#[cxx::bridge]` which
|
|
|
|
specifies a single function, to be called from C++, called `hello_from_rust`,
|
|
|
|
taking no parameters and returning no value.
|
|
|
|
- Modify your previous `hello_from_rust` function to remove `extern "C"` and
|
2024-11-01 07:39:56 +00:00
|
|
|
`#[unsafe(no_mangle)]`. This is now just a standard Rust function.
|
2023-12-31 00:15:07 +01:00
|
|
|
- Modify your `gn` target to build these bindings.
|
|
|
|
- In your C++ code, remove the forward-declaration of `hello_from_rust`.
|
|
|
|
Instead, include the generated header file.
|
|
|
|
- Build and run!
|
2023-11-27 18:21:19 +00:00
|
|
|
|
|
|
|
## Part two
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
It's a good idea to play with CXX a little. It helps you think about how
|
|
|
|
flexible Rust in Chromium actually is.
|
2023-11-27 18:21:19 +00:00
|
|
|
|
|
|
|
Some things to try:
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
- Call back into C++ from Rust. You will need:
|
|
|
|
- An additional header file which you can `include!` from your `cxx::bridge`.
|
2023-11-27 18:21:19 +00:00
|
|
|
You'll need to declare your C++ function in that new header file.
|
2023-12-31 00:15:07 +01:00
|
|
|
- An `unsafe` block to call such a function, or alternatively specify the
|
|
|
|
`unsafe` keyword in your `#[cxx::bridge]` [as described here][0].
|
|
|
|
- You may also need to
|
|
|
|
`#include "third_party/rust/cxx/v1/crate/include/cxx.h"`
|
|
|
|
- Pass a C++ string from C++ into Rust.
|
|
|
|
- Pass a reference to a C++ object into Rust.
|
|
|
|
- Intentionally get the Rust function signatures mismatched from the
|
|
|
|
`#[cxx::bridge]`, and get used to the errors you see.
|
|
|
|
- Intentionally get the C++ function signatures mismatched from the
|
|
|
|
`#[cxx::bridge]`, and get used to the errors you see.
|
|
|
|
- Pass a `std::unique_ptr` of some type from C++ into Rust, so that Rust can own
|
|
|
|
some C++ object.
|
|
|
|
- Create a Rust object and pass it into C++, so that C++ owns it. (Hint: you
|
|
|
|
need a `Box`).
|
|
|
|
- Declare some methods on a C++ type. Call them from Rust.
|
|
|
|
- Declare some methods on a Rust type. Call them from C++.
|
2023-11-27 18:21:19 +00:00
|
|
|
|
|
|
|
## Part three
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
Now you understand the strengths and limitations of CXX interop, think of a
|
|
|
|
couple of use-cases for Rust in Chromium where the interface would be
|
2023-11-27 18:21:19 +00:00
|
|
|
sufficiently simple. Sketch how you might define that interface.
|
|
|
|
|
|
|
|
## Where to find help
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
- The [`cxx` binding reference][1]
|
|
|
|
- The [`rust_static_library` gn template][2]
|
2023-11-27 18:21:19 +00:00
|
|
|
|
|
|
|
<details>
|
|
|
|
As students explore Part Two, they're bound to have lots of questions about how
|
2023-12-01 18:21:47 +00:00
|
|
|
to achieve these things, and also how CXX works behind the scenes.
|
2023-11-27 18:21:19 +00:00
|
|
|
|
|
|
|
Some of the questions you may encounter:
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
- I'm seeing a problem initializing a variable of type X with type Y, where X
|
|
|
|
and Y are both function types. This is because your C++ function doesn't quite
|
|
|
|
match the declaration in your `cxx::bridge`.
|
|
|
|
- I seem to be able to freely convert C++ references into Rust references.
|
|
|
|
Doesn't that risk UB? For CXX's _opaque_ types, no, because they are
|
|
|
|
zero-sized. For CXX trivial types yes, it's _possible_ to cause UB, although
|
|
|
|
CXX's design makes it quite difficult to craft such an example.
|
|
|
|
|
|
|
|
</details>
|
2023-11-27 18:21:19 +00:00
|
|
|
|
|
|
|
[0]: https://cxx.rs/extern-c++.html#functions-and-member-functions
|
|
|
|
[1]: https://cxx.rs/bindings.html
|
2023-12-31 00:15:07 +01:00
|
|
|
[2]: https://source.chromium.org/chromium/chromium/src/+/main:build/rust/rust_static_library.gni;l=16
|