This document tries to provide guidance for C++/Rust FFI. CLs to improve this guidance are welcomed.
Chromium recommends using the cxx
crate for C++/Rust FFI. For introductory guidance, please see the cxx
chapter in the Chromium day of the Comprehensive Rust course.
Chromium also supports the following tools:
bindgen
- see //build/rust/rust_bindgen.gni
for usage instructions.At this point Chromium's //build/rust/*.gni
templates do not support other FFI tools like:
We can‘t provide comprehensive, generic Rust guidance here, but let’s mention a few items that may be worth using in the FFI layer:
From
(or TryFrom
) is an idiomatic way of implementing a conversion between two types (e.g. between FFI layer types like ffi::ColorType
and third-party crate types like png::ColorType
). See an example trait implementation here and an example of spelling the conversion as foo.into()
here. Note that when implementing the conversion for types defined in other crates, you may need to work around the orphan rule by implementing Into
(or TryInto
) trait instead.
Question mark operator is an ergonomic, idiomatic way for checking errors. When using it in the FFI layer, this may require splitting some functions into 1) one that returns Result<T, E>
and uses ?
sugar, and 2) one that translates Result<T, E>
into FFI-friendly status. See an example here and here. Additional example here avoids having to come up with a separate name by using an anonymous function.
let Ok(foo) = ... else { ... }
is another ergonomic way for checking errors. See an example here.
cxx
guidancenamespace
. For example: #[cxx::bridge(namespace = "some_cpp_namespace")]
.#[cxx::bridge]
declaration. cxx
supports reusing types across multiple bridge
s, but there are some rough edges.TODO: Provide some examples or suggestions on how to structure FFI bindings (even if these suggestions wouldn't necessarily rise to the level of “best practices”).