blob: f98e4f09b23db83ff8d048e44bec3731ccc68f7d [file] [log] [blame] [view]
Lukasz Anforowiczdcdb524a2025-03-24 19:26:411# Rust FFI
2
3This document tries to provide guidance for C++/Rust FFI.
4CLs to improve this guidance are welcomed.
5
6## General guidance
7
Lukasz Anforowiczb878f002025-06-27 12:26:548### Supported FFI tools
9
Lukasz Anforowiczdcdb524a2025-03-24 19:26:4110Chromium recommends using [the `cxx` crate](https://cxx.rs/) for C++/Rust FFI.
11For introductory guidance, please see
12[the `cxx` chapter](https://google.github.io/comprehensive-rust/chromium/interoperability-with-cpp.html)
13in the Chromium day of the Comprehensive Rust course.
14
15Chromium also supports the following tools:
16
17* [`bindgen`](https://rust-lang.github.io/rust-bindgen/) - see
18 `//build/rust/rust_bindgen.gni` for usage instructions.
19
20At this point Chromium's `//build/rust/*.gni` templates do not support other FFI
21tools like:
22
23* [`cbindgen`](https://github.com/mozilla/cbindgen)
24* [`crubit`](https://github.com/google/crubit)
25
Lukasz Anforowiczb878f002025-06-27 12:26:5426### Related Rust idioms
Lukasz Anforowiczdcdb524a2025-03-24 19:26:4127
Lukasz Anforowiczb878f002025-06-27 12:26:5428We can't provide comprehensive, generic Rust guidance here, but let's
29mention a few items that may be worth using in the FFI layer:
30
31* [`From`](https://doc.rust-lang.org/std/convert/trait.From.html) (or
32 [`TryFrom`](https://doc.rust-lang.org/std/convert/trait.TryFrom.html))
33 is an idiomatic way of implementing a conversion between two types
34 (e.g. between FFI layer types like
35 [`ffi::ColorType`](https://source.chromium.org/chromium/chromium/src/+/main:third_party/skia/experimental/rust_png/ffi/FFI.rs;l=20-27;drc=70253db1ecfe261003756f0d81ae30929cc77ee4)
36 and third-party crate types like
37 [`png::ColorType`](https://docs.rs/png/0.17.6/png/enum.ColorType.html)).
38 See an example trait implementation
39 [here](https://source.chromium.org/chromium/chromium/src/+/main:third_party/skia/experimental/rust_png/ffi/FFI.rs;l=221-231;drc=70253db1ecfe261003756f0d81ae30929cc77ee4)
40 and an example of spelling the conversion as `foo.into()`
41 [here](https://source.chromium.org/chromium/chromium/src/+/main:third_party/skia/experimental/rust_png/ffi/FFI.rs;l=651;drc=70253db1ecfe261003756f0d81ae30929cc77ee4).
42 Note that when implementing the conversion for types defined in other crates,
43 you may need to work around the
44 [orphan rule](https://doc.rust-lang.org/reference/items/implementations.html#r-items.impl.trait.orphan-rule)
45 by implementing
46 [`Into`](https://doc.rust-lang.org/std/convert/trait.Into.html)
47 (or
48 [`TryInto`](https://doc.rust-lang.org/std/convert/trait.TryInto.html))
49 trait instead.
50
51* [Question mark operator](https://doc.rust-lang.org/reference/expressions/operator-expr.html#r-expr.try)
52 is an ergonomic, idiomatic way for checking errors.
53 When using it in the FFI layer, this may require splitting some functions
54 into 1) one that returns `Result<T, E>` and uses `?` sugar,
55 and 2) one that translates `Result<T, E>` into FFI-friendly
56 status. See an example
57 [here](https://source.chromium.org/chromium/chromium/src/+/main:components/user_data_importer/utility/zip_ffi_glue.rs;l=297;drc=33f81e080c4c06d18880ec04832511bda3929972)
58 and
59 [here](https://source.chromium.org/chromium/chromium/src/+/main:components/user_data_importer/utility/zip_ffi_glue.rs;l=421-427;drc=33f81e080c4c06d18880ec04832511bda3929972).
Lukasz Anforowiczaf3fafa2025-07-17 18:03:2760 Additional example
61 [here](https://chromium-review.googlesource.com/c/chromium/src/+/6733098/18/components/user_data_importer/utility/zip_ffi_glue.rs#484)
62 avoids having to come up with a separate name by using an anonymous function.
Lukasz Anforowiczb878f002025-06-27 12:26:5463
64* [`let Ok(foo) = ... else { ... }`](https://doc.rust-lang.org/rust-by-example/flow_control/let_else.html)
65 is another ergonomic way for checking errors. See
66 [an example here](https://source.chromium.org/chromium/chromium/src/+/main:components/user_data_importer/utility/zip_ffi_glue.rs;l=328-333;drc=33f81e080c4c06d18880ec04832511bda3929972).
67
68## `cxx` guidance
69
70### Best practices
Lukasz Anforowiczdcdb524a2025-03-24 19:26:4171
72* Generate C++ side of bindings into a project-specific or crate-specific
73 `namespace`. For example: `#[cxx::bridge(namespace = "some_cpp_namespace")]`.
74* Maintain binding declarations in a **single** `#[cxx::bridge]` declaration.
75 `cxx` supports reusing types across multiple `bridge`s, but there are some
76 rough edges.
77
Lukasz Anforowiczb878f002025-06-27 12:26:5478### Suggestions
Lukasz Anforowiczdcdb524a2025-03-24 19:26:4179
80TODO: Provide some examples or suggestions on how to structure FFI bindings
81(even if these suggestions wouldn't necessarily rise to the level of "best
82practices").