docs/rust/ffi.md
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
bindgen
tool.
See //build/rust/rust_bindgen.gni for usage instructions.
Consider using bindgen
if you want to generate Rust bindings based on a C/C++ header file,
without having to manually redeclare the C/C++ APIs in a #[cxx::bridge]
(e.g. if the number or complexity of the APIs would make it cumbersome
to author and maintain #[cxx::bridge] declarations).
Adding Chromium support for Crubit
is tracked in https://crbug.com/470466915, but the current integration is
incomplete at this point and not officially supported.
See cpp_api_from_rust.md for more details.
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 bridges, 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").