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** — 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** — 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** — 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 <=> 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>&str</td><td>rust::Str</td><td></td></tr> 32533d722a9Sopenharmony_ci<tr><td>&[T]</td><td>rust::Slice<const T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> 32633d722a9Sopenharmony_ci<tr><td>&mut [T]</td><td>rust::Slice<T></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<T></td><td>rust::Box<T></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<T></a></td><td>std::unique_ptr<T></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<T></a></td><td>std::shared_ptr<T></td><td><sup><i>cannot hold opaque Rust type</i></sup></td></tr> 33133d722a9Sopenharmony_ci<tr><td>[T; N]</td><td>std::array<T, N></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> 33233d722a9Sopenharmony_ci<tr><td>Vec<T></td><td>rust::Vec<T></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<T></a></td><td>std::vector<T></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) -> V</td><td>rust::Fn<V(T, U)></td><td><sup><i>only passing from Rust to C++ is implemented so far</i></sup></td></tr> 33633d722a9Sopenharmony_ci<tr><td>Result<T></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<K, V></td><td><sup><i>tbd</i></sup></td></tr> 35033d722a9Sopenharmony_ci<tr><td>HashMap<K, V></td><td><sup><i>tbd</i></sup></td></tr> 35133d722a9Sopenharmony_ci<tr><td>Arc<T></td><td><sup><i>tbd</i></sup></td></tr> 35233d722a9Sopenharmony_ci<tr><td>Option<T></td><td><sup><i>tbd</i></sup></td></tr> 35333d722a9Sopenharmony_ci<tr><td><sup><i>tbd</i></sup></td><td>std::map<K, V></td></tr> 35433d722a9Sopenharmony_ci<tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map<K, V></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