133d722a9Sopenharmony_ciCXX — safe FFI between Rust and C++
233d722a9Sopenharmony_ci=========================================
333d722a9Sopenharmony_ci
433d722a9Sopenharmony_ci[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/cxx-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/cxx)
533d722a9Sopenharmony_ci[<img alt="crates.io" src="https://img.shields.io/crates/v/cxx.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/cxx)
633d722a9Sopenharmony_ci[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-cxx-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/cxx)
733d722a9Sopenharmony_ci[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/cxx/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/cxx/actions?query=branch%3Amaster)
833d722a9Sopenharmony_ci
933d722a9Sopenharmony_ciThis library provides a **safe** mechanism for calling C++ code from Rust and
1033d722a9Sopenharmony_ciRust code from C++, not subject to the many ways that things can go wrong when
1133d722a9Sopenharmony_ciusing bindgen or cbindgen to generate unsafe C-style bindings.
1233d722a9Sopenharmony_ci
1333d722a9Sopenharmony_ciThis doesn't change the fact that 100% of C++ code is unsafe. When auditing a
1433d722a9Sopenharmony_ciproject, you would be on the hook for auditing all the unsafe Rust code and
1533d722a9Sopenharmony_ci*all* the C++ code. The core safety claim under this new model is that auditing
1633d722a9Sopenharmony_cijust the C++ side would be sufficient to catch all problems, i.e. the Rust side
1733d722a9Sopenharmony_cican be 100% safe.
1833d722a9Sopenharmony_ci
1933d722a9Sopenharmony_ci```toml
2033d722a9Sopenharmony_ci[dependencies]
2133d722a9Sopenharmony_cicxx = "1.0"
2233d722a9Sopenharmony_ci
2333d722a9Sopenharmony_ci[build-dependencies]
2433d722a9Sopenharmony_cicxx-build = "1.0"
2533d722a9Sopenharmony_ci```
2633d722a9Sopenharmony_ci
2733d722a9Sopenharmony_ci*Compiler support: requires rustc 1.60+ and c++11 or newer*<br>
2833d722a9Sopenharmony_ci*[Release notes](https://github.com/dtolnay/cxx/releases)*
2933d722a9Sopenharmony_ci
3033d722a9Sopenharmony_ci<br>
3133d722a9Sopenharmony_ci
3233d722a9Sopenharmony_ci## Guide
3333d722a9Sopenharmony_ci
3433d722a9Sopenharmony_ciPlease see **<https://cxx.rs>** for a tutorial, reference material, and example
3533d722a9Sopenharmony_cicode.
3633d722a9Sopenharmony_ci
3733d722a9Sopenharmony_ci<br>
3833d722a9Sopenharmony_ci
3933d722a9Sopenharmony_ci## Overview
4033d722a9Sopenharmony_ci
4133d722a9Sopenharmony_ciThe idea is that we define the signatures of both sides of our FFI boundary
4233d722a9Sopenharmony_ciembedded together in one Rust module (the next section shows an example). From
4333d722a9Sopenharmony_cithis, CXX receives a complete picture of the boundary to perform static analyses
4433d722a9Sopenharmony_ciagainst the types and function signatures to uphold both Rust's and C++'s
4533d722a9Sopenharmony_ciinvariants and requirements.
4633d722a9Sopenharmony_ci
4733d722a9Sopenharmony_ciIf everything checks out statically, then CXX uses a pair of code generators to
4833d722a9Sopenharmony_ciemit the relevant `extern "C"` signatures on both sides together with any
4933d722a9Sopenharmony_cinecessary static assertions for later in the build process to verify
5033d722a9Sopenharmony_cicorrectness. On the Rust side this code generator is simply an attribute
5133d722a9Sopenharmony_ciprocedural macro. On the C++ side it can be a small Cargo build script if your
5233d722a9Sopenharmony_cibuild is managed by Cargo, or for other build systems like Bazel or Buck we
5333d722a9Sopenharmony_ciprovide a command line tool which generates the header and source file and
5433d722a9Sopenharmony_cishould be easy to integrate.
5533d722a9Sopenharmony_ci
5633d722a9Sopenharmony_ciThe resulting FFI bridge operates at zero or negligible overhead, i.e. no
5733d722a9Sopenharmony_cicopying, no serialization, no memory allocation, no runtime checks needed.
5833d722a9Sopenharmony_ci
5933d722a9Sopenharmony_ciThe FFI signatures are able to use native types from whichever side they please,
6033d722a9Sopenharmony_cisuch as Rust's `String` or C++'s `std::string`, Rust's `Box` or C++'s
6133d722a9Sopenharmony_ci`std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any combination.
6233d722a9Sopenharmony_ciCXX guarantees an ABI-compatible signature that both sides understand, based on
6333d722a9Sopenharmony_cibuiltin bindings for key standard library types to expose an idiomatic API on
6433d722a9Sopenharmony_cithose types to the other language. For example when manipulating a C++ string
6533d722a9Sopenharmony_cifrom Rust, its `len()` method becomes a call of the `size()` member function
6633d722a9Sopenharmony_cidefined by C++; when manipulating a Rust string from C++, its `size()` member
6733d722a9Sopenharmony_cifunction calls Rust's `len()`.
6833d722a9Sopenharmony_ci
6933d722a9Sopenharmony_ci<br>
7033d722a9Sopenharmony_ci
7133d722a9Sopenharmony_ci## Example
7233d722a9Sopenharmony_ci
7333d722a9Sopenharmony_ciIn this example we are writing a Rust application that wishes to take advantage
7433d722a9Sopenharmony_ciof an existing C++ client for a large-file blobstore service. The blobstore
7533d722a9Sopenharmony_cisupports a `put` operation for a discontiguous buffer upload. For example we
7633d722a9Sopenharmony_cimight be uploading snapshots of a circular buffer which would tend to consist of
7733d722a9Sopenharmony_ci2 chunks, or fragments of a file spread across memory for some other reason.
7833d722a9Sopenharmony_ci
7933d722a9Sopenharmony_ciA runnable version of this example is provided under the *demo* directory of
8033d722a9Sopenharmony_cithis repo. To try it out, run `cargo run` from that directory.
8133d722a9Sopenharmony_ci
8233d722a9Sopenharmony_ci```rust
8333d722a9Sopenharmony_ci#[cxx::bridge]
8433d722a9Sopenharmony_cimod ffi {
8533d722a9Sopenharmony_ci    // Any shared structs, whose fields will be visible to both languages.
8633d722a9Sopenharmony_ci    struct BlobMetadata {
8733d722a9Sopenharmony_ci        size: usize,
8833d722a9Sopenharmony_ci        tags: Vec<String>,
8933d722a9Sopenharmony_ci    }
9033d722a9Sopenharmony_ci
9133d722a9Sopenharmony_ci    extern "Rust" {
9233d722a9Sopenharmony_ci        // Zero or more opaque types which both languages can pass around but
9333d722a9Sopenharmony_ci        // only Rust can see the fields.
9433d722a9Sopenharmony_ci        type MultiBuf;
9533d722a9Sopenharmony_ci
9633d722a9Sopenharmony_ci        // Functions implemented in Rust.
9733d722a9Sopenharmony_ci        fn next_chunk(buf: &mut MultiBuf) -> &[u8];
9833d722a9Sopenharmony_ci    }
9933d722a9Sopenharmony_ci
10033d722a9Sopenharmony_ci    unsafe extern "C++" {
10133d722a9Sopenharmony_ci        // One or more headers with the matching C++ declarations. Our code
10233d722a9Sopenharmony_ci        // generators don't read it but it gets #include'd and used in static
10333d722a9Sopenharmony_ci        // assertions to ensure our picture of the FFI boundary is accurate.
10433d722a9Sopenharmony_ci        include!("demo/include/blobstore.h");
10533d722a9Sopenharmony_ci
10633d722a9Sopenharmony_ci        // Zero or more opaque types which both languages can pass around but
10733d722a9Sopenharmony_ci        // only C++ can see the fields.
10833d722a9Sopenharmony_ci        type BlobstoreClient;
10933d722a9Sopenharmony_ci
11033d722a9Sopenharmony_ci        // Functions implemented in C++.
11133d722a9Sopenharmony_ci        fn new_blobstore_client() -> UniquePtr<BlobstoreClient>;
11233d722a9Sopenharmony_ci        fn put(&self, parts: &mut MultiBuf) -> u64;
11333d722a9Sopenharmony_ci        fn tag(&self, blobid: u64, tag: &str);
11433d722a9Sopenharmony_ci        fn metadata(&self, blobid: u64) -> BlobMetadata;
11533d722a9Sopenharmony_ci    }
11633d722a9Sopenharmony_ci}
11733d722a9Sopenharmony_ci```
11833d722a9Sopenharmony_ci
11933d722a9Sopenharmony_ciNow we simply provide Rust definitions of all the things in the `extern "Rust"`
12033d722a9Sopenharmony_ciblock and C++ definitions of all the things in the `extern "C++"` block, and get
12133d722a9Sopenharmony_cito call back and forth safely.
12233d722a9Sopenharmony_ci
12333d722a9Sopenharmony_ciHere are links to the complete set of source files involved in the demo:
12433d722a9Sopenharmony_ci
12533d722a9Sopenharmony_ci- [demo/src/main.rs](demo/src/main.rs)
12633d722a9Sopenharmony_ci- [demo/build.rs](demo/build.rs)
12733d722a9Sopenharmony_ci- [demo/include/blobstore.h](demo/include/blobstore.h)
12833d722a9Sopenharmony_ci- [demo/src/blobstore.cc](demo/src/blobstore.cc)
12933d722a9Sopenharmony_ci
13033d722a9Sopenharmony_ciTo look at the code generated in both languages for the example by the CXX code
13133d722a9Sopenharmony_cigenerators:
13233d722a9Sopenharmony_ci
13333d722a9Sopenharmony_ci```console
13433d722a9Sopenharmony_ci   # run Rust code generator and print to stdout
13533d722a9Sopenharmony_ci   # (requires https://github.com/dtolnay/cargo-expand)
13633d722a9Sopenharmony_ci$ cargo expand --manifest-path demo/Cargo.toml
13733d722a9Sopenharmony_ci
13833d722a9Sopenharmony_ci   # run C++ code generator and print to stdout
13933d722a9Sopenharmony_ci$ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs
14033d722a9Sopenharmony_ci```
14133d722a9Sopenharmony_ci
14233d722a9Sopenharmony_ci<br>
14333d722a9Sopenharmony_ci
14433d722a9Sopenharmony_ci## Details
14533d722a9Sopenharmony_ci
14633d722a9Sopenharmony_ciAs seen in the example, the language of the FFI boundary involves 3 kinds of
14733d722a9Sopenharmony_ciitems:
14833d722a9Sopenharmony_ci
14933d722a9Sopenharmony_ci- **Shared structs** &mdash; their fields are made visible to both languages.
15033d722a9Sopenharmony_ci  The definition written within cxx::bridge is the single source of truth.
15133d722a9Sopenharmony_ci
15233d722a9Sopenharmony_ci- **Opaque types** &mdash; their fields are secret from the other language.
15333d722a9Sopenharmony_ci  These cannot be passed across the FFI by value but only behind an indirection,
15433d722a9Sopenharmony_ci  such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can be a type alias
15533d722a9Sopenharmony_ci  for an arbitrarily complicated generic language-specific type depending on
15633d722a9Sopenharmony_ci  your use case.
15733d722a9Sopenharmony_ci
15833d722a9Sopenharmony_ci- **Functions** &mdash; implemented in either language, callable from the other
15933d722a9Sopenharmony_ci  language.
16033d722a9Sopenharmony_ci
16133d722a9Sopenharmony_ciWithin the `extern "Rust"` part of the CXX bridge we list the types and
16233d722a9Sopenharmony_cifunctions for which Rust is the source of truth. These all implicitly refer to
16333d722a9Sopenharmony_cithe `super` module, the parent module of the CXX bridge. You can think of the
16433d722a9Sopenharmony_citwo items listed in the example above as being like `use super::MultiBuf` and
16533d722a9Sopenharmony_ci`use super::next_chunk` except re-exported to C++. The parent module will either
16633d722a9Sopenharmony_cicontain the definitions directly for simple things, or contain the relevant
16733d722a9Sopenharmony_ci`use` statements to bring them into scope from elsewhere.
16833d722a9Sopenharmony_ci
16933d722a9Sopenharmony_ciWithin the `extern "C++"` part, we list types and functions for which C++ is the
17033d722a9Sopenharmony_cisource of truth, as well as the header(s) that declare those APIs. In the future
17133d722a9Sopenharmony_ciit's possible that this section could be generated bindgen-style from the
17233d722a9Sopenharmony_ciheaders but for now we need the signatures written out; static assertions will
17333d722a9Sopenharmony_civerify that they are accurate.
17433d722a9Sopenharmony_ci
17533d722a9Sopenharmony_ciYour function implementations themselves, whether in C++ or Rust, *do not* need
17633d722a9Sopenharmony_cito be defined as `extern "C"` ABI or no\_mangle. CXX will put in the right shims
17733d722a9Sopenharmony_ciwhere necessary to make it all work.
17833d722a9Sopenharmony_ci
17933d722a9Sopenharmony_ci<br>
18033d722a9Sopenharmony_ci
18133d722a9Sopenharmony_ci## Comparison vs bindgen and cbindgen
18233d722a9Sopenharmony_ci
18333d722a9Sopenharmony_ciNotice that with CXX there is repetition of all the function signatures: they
18433d722a9Sopenharmony_ciare typed out once where the implementation is defined (in C++ or Rust) and
18533d722a9Sopenharmony_ciagain inside the cxx::bridge module, though compile-time assertions guarantee
18633d722a9Sopenharmony_cithese are kept in sync. This is different from [bindgen] and [cbindgen] where
18733d722a9Sopenharmony_cifunction signatures are typed by a human once and the tool consumes them in one
18833d722a9Sopenharmony_cilanguage and emits them in the other language.
18933d722a9Sopenharmony_ci
19033d722a9Sopenharmony_ci[bindgen]: https://github.com/rust-lang/rust-bindgen
19133d722a9Sopenharmony_ci[cbindgen]: https://github.com/eqrion/cbindgen/
19233d722a9Sopenharmony_ci
19333d722a9Sopenharmony_ciThis is because CXX fills a somewhat different role. It is a lower level tool
19433d722a9Sopenharmony_cithan bindgen or cbindgen in a sense; you can think of it as being a replacement
19533d722a9Sopenharmony_cifor the concept of `extern "C"` signatures as we know them, rather than a
19633d722a9Sopenharmony_cireplacement for a bindgen. It would be reasonable to build a higher level
19733d722a9Sopenharmony_cibindgen-like tool on top of CXX which consumes a C++ header and/or Rust module
19833d722a9Sopenharmony_ci(and/or IDL like Thrift) as source of truth and generates the cxx::bridge,
19933d722a9Sopenharmony_cieliminating the repetition while leveraging the static analysis safety
20033d722a9Sopenharmony_ciguarantees of CXX.
20133d722a9Sopenharmony_ci
20233d722a9Sopenharmony_ciBut note in other ways CXX is higher level than the bindgens, with rich support
20333d722a9Sopenharmony_cifor common standard library types. Frequently with bindgen when we are dealing
20433d722a9Sopenharmony_ciwith an idiomatic C++ API we would end up manually wrapping that API in C-style
20533d722a9Sopenharmony_ciraw pointer functions, applying bindgen to get unsafe raw pointer Rust
20633d722a9Sopenharmony_cifunctions, and replicating the API again to expose those idiomatically in Rust.
20733d722a9Sopenharmony_ciThat's a much worse form of repetition because it is unsafe all the way through.
20833d722a9Sopenharmony_ci
20933d722a9Sopenharmony_ciBy using a CXX bridge as the shared understanding between the languages, rather
21033d722a9Sopenharmony_cithan `extern "C"` C-style signatures as the shared understanding, common FFI use
21133d722a9Sopenharmony_cicases become expressible using 100% safe code.
21233d722a9Sopenharmony_ci
21333d722a9Sopenharmony_ciIt would also be reasonable to mix and match, using CXX bridge for the 95% of
21433d722a9Sopenharmony_ciyour FFI that is straightforward and doing the remaining few oddball signatures
21533d722a9Sopenharmony_cithe old fashioned way with bindgen and cbindgen, if for some reason CXX's static
21633d722a9Sopenharmony_cirestrictions get in the way. Please file an issue if you end up taking this
21733d722a9Sopenharmony_ciapproach so that we know what ways it would be worthwhile to make the tool more
21833d722a9Sopenharmony_ciexpressive.
21933d722a9Sopenharmony_ci
22033d722a9Sopenharmony_ci<br>
22133d722a9Sopenharmony_ci
22233d722a9Sopenharmony_ci## Cargo-based setup
22333d722a9Sopenharmony_ci
22433d722a9Sopenharmony_ciFor builds that are orchestrated by Cargo, you will use a build script that runs
22533d722a9Sopenharmony_ciCXX's C++ code generator and compiles the resulting C++ code along with any
22633d722a9Sopenharmony_ciother C++ code for your crate.
22733d722a9Sopenharmony_ci
22833d722a9Sopenharmony_ciThe canonical build script is as follows. The indicated line returns a
22933d722a9Sopenharmony_ci[`cc::Build`] instance (from the usual widely used `cc` crate) on which you can
23033d722a9Sopenharmony_ciset up any additional source files and compiler flags as normal.
23133d722a9Sopenharmony_ci
23233d722a9Sopenharmony_ci[`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html
23333d722a9Sopenharmony_ci
23433d722a9Sopenharmony_ci```toml
23533d722a9Sopenharmony_ci# Cargo.toml
23633d722a9Sopenharmony_ci
23733d722a9Sopenharmony_ci[build-dependencies]
23833d722a9Sopenharmony_cicxx-build = "1.0"
23933d722a9Sopenharmony_ci```
24033d722a9Sopenharmony_ci
24133d722a9Sopenharmony_ci```rust
24233d722a9Sopenharmony_ci// build.rs
24333d722a9Sopenharmony_ci
24433d722a9Sopenharmony_cifn main() {
24533d722a9Sopenharmony_ci    cxx_build::bridge("src/main.rs")  // returns a cc::Build
24633d722a9Sopenharmony_ci        .file("src/demo.cc")
24733d722a9Sopenharmony_ci        .flag_if_supported("-std=c++11")
24833d722a9Sopenharmony_ci        .compile("cxxbridge-demo");
24933d722a9Sopenharmony_ci
25033d722a9Sopenharmony_ci    println!("cargo:rerun-if-changed=src/main.rs");
25133d722a9Sopenharmony_ci    println!("cargo:rerun-if-changed=src/demo.cc");
25233d722a9Sopenharmony_ci    println!("cargo:rerun-if-changed=include/demo.h");
25333d722a9Sopenharmony_ci}
25433d722a9Sopenharmony_ci```
25533d722a9Sopenharmony_ci
25633d722a9Sopenharmony_ci<br>
25733d722a9Sopenharmony_ci
25833d722a9Sopenharmony_ci## Non-Cargo setup
25933d722a9Sopenharmony_ci
26033d722a9Sopenharmony_ciFor use in non-Cargo builds like Bazel or Buck, CXX provides an alternate way of
26133d722a9Sopenharmony_ciinvoking the C++ code generator as a standalone command line tool. The tool is
26233d722a9Sopenharmony_cipackaged as the `cxxbridge-cmd` crate on crates.io or can be built from the
26333d722a9Sopenharmony_ci*gen/cmd* directory of this repo.
26433d722a9Sopenharmony_ci
26533d722a9Sopenharmony_ci```bash
26633d722a9Sopenharmony_ci$ cargo install cxxbridge-cmd
26733d722a9Sopenharmony_ci
26833d722a9Sopenharmony_ci$ cxxbridge src/main.rs --header > path/to/mybridge.h
26933d722a9Sopenharmony_ci$ cxxbridge src/main.rs > path/to/mybridge.cc
27033d722a9Sopenharmony_ci```
27133d722a9Sopenharmony_ci
27233d722a9Sopenharmony_ci<br>
27333d722a9Sopenharmony_ci
27433d722a9Sopenharmony_ci## Safety
27533d722a9Sopenharmony_ci
27633d722a9Sopenharmony_ciBe aware that the design of this library is intentionally restrictive and
27733d722a9Sopenharmony_ciopinionated! It isn't a goal to be powerful enough to handle arbitrary
27833d722a9Sopenharmony_cisignatures in either language. Instead this project is about carving out a
27933d722a9Sopenharmony_cireasonably expressive set of functionality about which we can make useful safety
28033d722a9Sopenharmony_ciguarantees today and maybe extend over time. You may find that it takes some
28133d722a9Sopenharmony_cipractice to use CXX bridge effectively as it won't work in all the ways that you
28233d722a9Sopenharmony_ciare used to.
28333d722a9Sopenharmony_ci
28433d722a9Sopenharmony_ciSome of the considerations that go into ensuring safety are:
28533d722a9Sopenharmony_ci
28633d722a9Sopenharmony_ci- By design, our paired code generators work together to control both sides of
28733d722a9Sopenharmony_ci  the FFI boundary. Ordinarily in Rust writing your own `extern "C"` blocks is
28833d722a9Sopenharmony_ci  unsafe because the Rust compiler has no way to know whether the signatures
28933d722a9Sopenharmony_ci  you've written actually match the signatures implemented in the other
29033d722a9Sopenharmony_ci  language. With CXX we achieve that visibility and know what's on the other
29133d722a9Sopenharmony_ci  side.
29233d722a9Sopenharmony_ci
29333d722a9Sopenharmony_ci- Our static analysis detects and prevents passing types by value that shouldn't
29433d722a9Sopenharmony_ci  be passed by value from C++ to Rust, for example because they may contain
29533d722a9Sopenharmony_ci  internal pointers that would be screwed up by Rust's move behavior.
29633d722a9Sopenharmony_ci
29733d722a9Sopenharmony_ci- To many people's surprise, it is possible to have a struct in Rust and a
29833d722a9Sopenharmony_ci  struct in C++ with exactly the same layout / fields / alignment / everything,
29933d722a9Sopenharmony_ci  and still not the same ABI when passed by value. This is a longstanding
30033d722a9Sopenharmony_ci  bindgen bug that leads to segfaults in absolutely correct-looking code
30133d722a9Sopenharmony_ci  ([rust-lang/rust-bindgen#778]). CXX knows about this and can insert the
30233d722a9Sopenharmony_ci  necessary zero-cost workaround transparently where needed, so go ahead and
30333d722a9Sopenharmony_ci  pass your structs by value without worries. This is made possible by owning
30433d722a9Sopenharmony_ci  both sides of the boundary rather than just one.
30533d722a9Sopenharmony_ci
30633d722a9Sopenharmony_ci- Template instantiations: for example in order to expose a UniquePtr\<T\> type
30733d722a9Sopenharmony_ci  in Rust backed by a real C++ unique\_ptr, we have a way of using a Rust trait
30833d722a9Sopenharmony_ci  to connect the behavior back to the template instantiations performed by the
30933d722a9Sopenharmony_ci  other language.
31033d722a9Sopenharmony_ci
31133d722a9Sopenharmony_ci[rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778
31233d722a9Sopenharmony_ci
31333d722a9Sopenharmony_ci<br>
31433d722a9Sopenharmony_ci
31533d722a9Sopenharmony_ci## Builtin types
31633d722a9Sopenharmony_ci
31733d722a9Sopenharmony_ciIn addition to all the primitive types (i32 &lt;=&gt; int32_t), the following
31833d722a9Sopenharmony_cicommon types may be used in the fields of shared structs and the arguments and
31933d722a9Sopenharmony_cireturns of functions.
32033d722a9Sopenharmony_ci
32133d722a9Sopenharmony_ci<table>
32233d722a9Sopenharmony_ci<tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr>
32333d722a9Sopenharmony_ci<tr><td>String</td><td>rust::String</td><td></td></tr>
32433d722a9Sopenharmony_ci<tr><td>&amp;str</td><td>rust::Str</td><td></td></tr>
32533d722a9Sopenharmony_ci<tr><td>&amp;[T]</td><td>rust::Slice&lt;const T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
32633d722a9Sopenharmony_ci<tr><td>&amp;mut [T]</td><td>rust::Slice&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
32733d722a9Sopenharmony_ci<tr><td><a href="https://docs.rs/cxx/1.0/cxx/struct.CxxString.html">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr>
32833d722a9Sopenharmony_ci<tr><td>Box&lt;T&gt;</td><td>rust::Box&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
32933d722a9Sopenharmony_ci<tr><td><a href="https://docs.rs/cxx/1.0/cxx/struct.UniquePtr.html">UniquePtr&lt;T&gt;</a></td><td>std::unique_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>
33033d722a9Sopenharmony_ci<tr><td><a href="https://docs.rs/cxx/1.0/cxx/struct.SharedPtr.html">SharedPtr&lt;T&gt;</a></td><td>std::shared_ptr&lt;T&gt;</td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr>
33133d722a9Sopenharmony_ci<tr><td>[T; N]</td><td>std::array&lt;T, N&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
33233d722a9Sopenharmony_ci<tr><td>Vec&lt;T&gt;</td><td>rust::Vec&lt;T&gt;</td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr>
33333d722a9Sopenharmony_ci<tr><td><a href="https://docs.rs/cxx/1.0/cxx/struct.CxxVector.html">CxxVector&lt;T&gt;</a></td><td>std::vector&lt;T&gt;</td><td><sup><i>cannot be passed by value, cannot hold opaque Rust type</i></sup></td></tr>
33433d722a9Sopenharmony_ci<tr><td>*mut T, *const T</td><td>T*, const T*</td><td><sup><i>fn with a raw pointer argument must be declared unsafe to call</i></sup></td></tr>
33533d722a9Sopenharmony_ci<tr><td>fn(T, U) -&gt; V</td><td>rust::Fn&lt;V(T, U)&gt;</td><td><sup><i>only passing from Rust to C++ is implemented so far</i></sup></td></tr>
33633d722a9Sopenharmony_ci<tr><td>Result&lt;T&gt;</td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr>
33733d722a9Sopenharmony_ci</table>
33833d722a9Sopenharmony_ci
33933d722a9Sopenharmony_ciThe C++ API of the `rust` namespace is defined by the *include/cxx.h* file in
34033d722a9Sopenharmony_cithis repo. You will need to include this header in your C++ code when working
34133d722a9Sopenharmony_ciwith those types.
34233d722a9Sopenharmony_ci
34333d722a9Sopenharmony_ciThe following types are intended to be supported "soon" but are just not
34433d722a9Sopenharmony_ciimplemented yet. I don't expect any of these to be hard to make work but it's a
34533d722a9Sopenharmony_cimatter of designing a nice API for each in its non-native language.
34633d722a9Sopenharmony_ci
34733d722a9Sopenharmony_ci<table>
34833d722a9Sopenharmony_ci<tr><th>name in Rust</th><th>name in C++</th></tr>
34933d722a9Sopenharmony_ci<tr><td>BTreeMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>
35033d722a9Sopenharmony_ci<tr><td>HashMap&lt;K, V&gt;</td><td><sup><i>tbd</i></sup></td></tr>
35133d722a9Sopenharmony_ci<tr><td>Arc&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>
35233d722a9Sopenharmony_ci<tr><td>Option&lt;T&gt;</td><td><sup><i>tbd</i></sup></td></tr>
35333d722a9Sopenharmony_ci<tr><td><sup><i>tbd</i></sup></td><td>std::map&lt;K, V&gt;</td></tr>
35433d722a9Sopenharmony_ci<tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map&lt;K, V&gt;</td></tr>
35533d722a9Sopenharmony_ci</table>
35633d722a9Sopenharmony_ci
35733d722a9Sopenharmony_ci<br>
35833d722a9Sopenharmony_ci
35933d722a9Sopenharmony_ci## Remaining work
36033d722a9Sopenharmony_ci
36133d722a9Sopenharmony_ciThis is still early days for CXX; I am releasing it as a minimum viable product
36233d722a9Sopenharmony_cito collect feedback on the direction and invite collaborators. Please check the
36333d722a9Sopenharmony_ciopen issues.
36433d722a9Sopenharmony_ci
36533d722a9Sopenharmony_ciEspecially please report issues if you run into trouble building or linking any
36633d722a9Sopenharmony_ciof this stuff. I'm sure there are ways to make the build aspects friendlier or
36733d722a9Sopenharmony_cimore robust.
36833d722a9Sopenharmony_ci
36933d722a9Sopenharmony_ciFinally, I know more about Rust library design than C++ library design so I
37033d722a9Sopenharmony_ciwould appreciate help making the C++ APIs in this project more idiomatic where
37133d722a9Sopenharmony_cianyone has suggestions.
37233d722a9Sopenharmony_ci
37333d722a9Sopenharmony_ci<br>
37433d722a9Sopenharmony_ci
37533d722a9Sopenharmony_ci#### License
37633d722a9Sopenharmony_ci
37733d722a9Sopenharmony_ci<sup>
37833d722a9Sopenharmony_ciLicensed under either of <a href="LICENSE-APACHE">Apache License, Version
37933d722a9Sopenharmony_ci2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
38033d722a9Sopenharmony_ci</sup>
38133d722a9Sopenharmony_ci
38233d722a9Sopenharmony_ci<br>
38333d722a9Sopenharmony_ci
38433d722a9Sopenharmony_ci<sub>
38533d722a9Sopenharmony_ciUnless you explicitly state otherwise, any contribution intentionally submitted
38633d722a9Sopenharmony_cifor inclusion in this project by you, as defined in the Apache-2.0 license,
38733d722a9Sopenharmony_cishall be dual licensed as above, without any additional terms or conditions.
38833d722a9Sopenharmony_ci</sub>
389