Rust FFI

This document tries to provide guidance for C++/Rust FFI. CLs to improve this guidance are welcomed.

General guidance

Supported FFI tools

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:

Related Rust idioms

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 guidance

Best practices

  • Generate C++ side of bindings into a project-specific or crate-specific namespace. For example: #[cxx::bridge(namespace = "some_cpp_namespace")].
  • Maintain binding declarations in a single #[cxx::bridge] declaration. cxx supports reusing types across multiple bridges, but there are some rough edges.

Suggestions

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”).