133d722a9Sopenharmony_ci//! [![github]](https://github.com/dtolnay/cxx) [![crates-io]](https://crates.io/crates/cxx) [![docs-rs]](https://docs.rs/cxx) 233d722a9Sopenharmony_ci//! 333d722a9Sopenharmony_ci//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github 433d722a9Sopenharmony_ci//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust 533d722a9Sopenharmony_ci//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs 633d722a9Sopenharmony_ci//! 733d722a9Sopenharmony_ci//! <br> 833d722a9Sopenharmony_ci//! 933d722a9Sopenharmony_ci//! This library provides a **safe** mechanism for calling C++ code from Rust 1033d722a9Sopenharmony_ci//! and Rust code from C++, not subject to the many ways that things can go 1133d722a9Sopenharmony_ci//! wrong when using bindgen or cbindgen to generate unsafe C-style bindings. 1233d722a9Sopenharmony_ci//! 1333d722a9Sopenharmony_ci//! This doesn't change the fact that 100% of C++ code is unsafe. When auditing 1433d722a9Sopenharmony_ci//! a project, you would be on the hook for auditing all the unsafe Rust code 1533d722a9Sopenharmony_ci//! and *all* the C++ code. The core safety claim under this new model is that 1633d722a9Sopenharmony_ci//! auditing just the C++ side would be sufficient to catch all problems, i.e. 1733d722a9Sopenharmony_ci//! the Rust side can be 100% safe. 1833d722a9Sopenharmony_ci//! 1933d722a9Sopenharmony_ci//! <br> 2033d722a9Sopenharmony_ci//! 2133d722a9Sopenharmony_ci//! *Compiler support: requires rustc 1.60+ and c++11 or newer*<br> 2233d722a9Sopenharmony_ci//! *[Release notes](https://github.com/dtolnay/cxx/releases)* 2333d722a9Sopenharmony_ci//! 2433d722a9Sopenharmony_ci//! <br> 2533d722a9Sopenharmony_ci//! 2633d722a9Sopenharmony_ci//! # Guide 2733d722a9Sopenharmony_ci//! 2833d722a9Sopenharmony_ci//! Please see **<https://cxx.rs>** for a tutorial, reference material, and 2933d722a9Sopenharmony_ci//! example code. 3033d722a9Sopenharmony_ci//! 3133d722a9Sopenharmony_ci//! <br> 3233d722a9Sopenharmony_ci//! 3333d722a9Sopenharmony_ci//! # Overview 3433d722a9Sopenharmony_ci//! 3533d722a9Sopenharmony_ci//! The idea is that we define the signatures of both sides of our FFI boundary 3633d722a9Sopenharmony_ci//! embedded together in one Rust module (the next section shows an example). 3733d722a9Sopenharmony_ci//! From this, CXX receives a complete picture of the boundary to perform static 3833d722a9Sopenharmony_ci//! analyses against the types and function signatures to uphold both Rust's and 3933d722a9Sopenharmony_ci//! C++'s invariants and requirements. 4033d722a9Sopenharmony_ci//! 4133d722a9Sopenharmony_ci//! If everything checks out statically, then CXX uses a pair of code generators 4233d722a9Sopenharmony_ci//! to emit the relevant `extern "C"` signatures on both sides together with any 4333d722a9Sopenharmony_ci//! necessary static assertions for later in the build process to verify 4433d722a9Sopenharmony_ci//! correctness. On the Rust side this code generator is simply an attribute 4533d722a9Sopenharmony_ci//! procedural macro. On the C++ side it can be a small Cargo build script if 4633d722a9Sopenharmony_ci//! your build is managed by Cargo, or for other build systems like Bazel or 4733d722a9Sopenharmony_ci//! Buck we provide a command line tool which generates the header and source 4833d722a9Sopenharmony_ci//! file and should be easy to integrate. 4933d722a9Sopenharmony_ci//! 5033d722a9Sopenharmony_ci//! The resulting FFI bridge operates at zero or negligible overhead, i.e. no 5133d722a9Sopenharmony_ci//! copying, no serialization, no memory allocation, no runtime checks needed. 5233d722a9Sopenharmony_ci//! 5333d722a9Sopenharmony_ci//! The FFI signatures are able to use native types from whichever side they 5433d722a9Sopenharmony_ci//! please, such as Rust's `String` or C++'s `std::string`, Rust's `Box` or 5533d722a9Sopenharmony_ci//! C++'s `std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any 5633d722a9Sopenharmony_ci//! combination. CXX guarantees an ABI-compatible signature that both sides 5733d722a9Sopenharmony_ci//! understand, based on builtin bindings for key standard library types to 5833d722a9Sopenharmony_ci//! expose an idiomatic API on those types to the other language. For example 5933d722a9Sopenharmony_ci//! when manipulating a C++ string from Rust, its `len()` method becomes a call 6033d722a9Sopenharmony_ci//! of the `size()` member function defined by C++; when manipulation a Rust 6133d722a9Sopenharmony_ci//! string from C++, its `size()` member function calls Rust's `len()`. 6233d722a9Sopenharmony_ci//! 6333d722a9Sopenharmony_ci//! <br> 6433d722a9Sopenharmony_ci//! 6533d722a9Sopenharmony_ci//! # Example 6633d722a9Sopenharmony_ci//! 6733d722a9Sopenharmony_ci//! In this example we are writing a Rust application that wishes to take 6833d722a9Sopenharmony_ci//! advantage of an existing C++ client for a large-file blobstore service. The 6933d722a9Sopenharmony_ci//! blobstore supports a `put` operation for a discontiguous buffer upload. For 7033d722a9Sopenharmony_ci//! example we might be uploading snapshots of a circular buffer which would 7133d722a9Sopenharmony_ci//! tend to consist of 2 chunks, or fragments of a file spread across memory for 7233d722a9Sopenharmony_ci//! some other reason. 7333d722a9Sopenharmony_ci//! 7433d722a9Sopenharmony_ci//! A runnable version of this example is provided under the *demo* directory of 7533d722a9Sopenharmony_ci//! <https://github.com/dtolnay/cxx>. To try it out, run `cargo run` from that 7633d722a9Sopenharmony_ci//! directory. 7733d722a9Sopenharmony_ci//! 7833d722a9Sopenharmony_ci//! ```no_run 7933d722a9Sopenharmony_ci//! #[cxx::bridge] 8033d722a9Sopenharmony_ci//! mod ffi { 8133d722a9Sopenharmony_ci//! // Any shared structs, whose fields will be visible to both languages. 8233d722a9Sopenharmony_ci//! struct BlobMetadata { 8333d722a9Sopenharmony_ci//! size: usize, 8433d722a9Sopenharmony_ci//! tags: Vec<String>, 8533d722a9Sopenharmony_ci//! } 8633d722a9Sopenharmony_ci//! 8733d722a9Sopenharmony_ci//! extern "Rust" { 8833d722a9Sopenharmony_ci//! // Zero or more opaque types which both languages can pass around but 8933d722a9Sopenharmony_ci//! // only Rust can see the fields. 9033d722a9Sopenharmony_ci//! type MultiBuf; 9133d722a9Sopenharmony_ci//! 9233d722a9Sopenharmony_ci//! // Functions implemented in Rust. 9333d722a9Sopenharmony_ci//! fn next_chunk(buf: &mut MultiBuf) -> &[u8]; 9433d722a9Sopenharmony_ci//! } 9533d722a9Sopenharmony_ci//! 9633d722a9Sopenharmony_ci//! unsafe extern "C++" { 9733d722a9Sopenharmony_ci//! // One or more headers with the matching C++ declarations. Our code 9833d722a9Sopenharmony_ci//! // generators don't read it but it gets #include'd and used in static 9933d722a9Sopenharmony_ci//! // assertions to ensure our picture of the FFI boundary is accurate. 10033d722a9Sopenharmony_ci//! include!("demo/include/blobstore.h"); 10133d722a9Sopenharmony_ci//! 10233d722a9Sopenharmony_ci//! // Zero or more opaque types which both languages can pass around but 10333d722a9Sopenharmony_ci//! // only C++ can see the fields. 10433d722a9Sopenharmony_ci//! type BlobstoreClient; 10533d722a9Sopenharmony_ci//! 10633d722a9Sopenharmony_ci//! // Functions implemented in C++. 10733d722a9Sopenharmony_ci//! fn new_blobstore_client() -> UniquePtr<BlobstoreClient>; 10833d722a9Sopenharmony_ci//! fn put(&self, parts: &mut MultiBuf) -> u64; 10933d722a9Sopenharmony_ci//! fn tag(&self, blobid: u64, tag: &str); 11033d722a9Sopenharmony_ci//! fn metadata(&self, blobid: u64) -> BlobMetadata; 11133d722a9Sopenharmony_ci//! } 11233d722a9Sopenharmony_ci//! } 11333d722a9Sopenharmony_ci//! # 11433d722a9Sopenharmony_ci//! # pub struct MultiBuf; 11533d722a9Sopenharmony_ci//! # 11633d722a9Sopenharmony_ci//! # fn next_chunk(_buf: &mut MultiBuf) -> &[u8] { 11733d722a9Sopenharmony_ci//! # unimplemented!() 11833d722a9Sopenharmony_ci//! # } 11933d722a9Sopenharmony_ci//! # 12033d722a9Sopenharmony_ci//! # fn main() {} 12133d722a9Sopenharmony_ci//! ``` 12233d722a9Sopenharmony_ci//! 12333d722a9Sopenharmony_ci//! Now we simply provide Rust definitions of all the things in the `extern 12433d722a9Sopenharmony_ci//! "Rust"` block and C++ definitions of all the things in the `extern "C++"` 12533d722a9Sopenharmony_ci//! block, and get to call back and forth safely. 12633d722a9Sopenharmony_ci//! 12733d722a9Sopenharmony_ci//! Here are links to the complete set of source files involved in the demo: 12833d722a9Sopenharmony_ci//! 12933d722a9Sopenharmony_ci//! - [demo/src/main.rs](https://github.com/dtolnay/cxx/blob/master/demo/src/main.rs) 13033d722a9Sopenharmony_ci//! - [demo/build.rs](https://github.com/dtolnay/cxx/blob/master/demo/build.rs) 13133d722a9Sopenharmony_ci//! - [demo/include/blobstore.h](https://github.com/dtolnay/cxx/blob/master/demo/include/blobstore.h) 13233d722a9Sopenharmony_ci//! - [demo/src/blobstore.cc](https://github.com/dtolnay/cxx/blob/master/demo/src/blobstore.cc) 13333d722a9Sopenharmony_ci//! 13433d722a9Sopenharmony_ci//! To look at the code generated in both languages for the example by the CXX 13533d722a9Sopenharmony_ci//! code generators: 13633d722a9Sopenharmony_ci//! 13733d722a9Sopenharmony_ci//! ```console 13833d722a9Sopenharmony_ci//! # run Rust code generator and print to stdout 13933d722a9Sopenharmony_ci//! # (requires https://github.com/dtolnay/cargo-expand) 14033d722a9Sopenharmony_ci//! $ cargo expand --manifest-path demo/Cargo.toml 14133d722a9Sopenharmony_ci//! 14233d722a9Sopenharmony_ci//! # run C++ code generator and print to stdout 14333d722a9Sopenharmony_ci//! $ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs 14433d722a9Sopenharmony_ci//! ``` 14533d722a9Sopenharmony_ci//! 14633d722a9Sopenharmony_ci//! <br> 14733d722a9Sopenharmony_ci//! 14833d722a9Sopenharmony_ci//! # Details 14933d722a9Sopenharmony_ci//! 15033d722a9Sopenharmony_ci//! As seen in the example, the language of the FFI boundary involves 3 kinds of 15133d722a9Sopenharmony_ci//! items: 15233d722a9Sopenharmony_ci//! 15333d722a9Sopenharmony_ci//! - **Shared structs** — their fields are made visible to both 15433d722a9Sopenharmony_ci//! languages. The definition written within cxx::bridge is the single source 15533d722a9Sopenharmony_ci//! of truth. 15633d722a9Sopenharmony_ci//! 15733d722a9Sopenharmony_ci//! - **Opaque types** — their fields are secret from the other language. 15833d722a9Sopenharmony_ci//! These cannot be passed across the FFI by value but only behind an 15933d722a9Sopenharmony_ci//! indirection, such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can 16033d722a9Sopenharmony_ci//! be a type alias for an arbitrarily complicated generic language-specific 16133d722a9Sopenharmony_ci//! type depending on your use case. 16233d722a9Sopenharmony_ci//! 16333d722a9Sopenharmony_ci//! - **Functions** — implemented in either language, callable from the 16433d722a9Sopenharmony_ci//! other language. 16533d722a9Sopenharmony_ci//! 16633d722a9Sopenharmony_ci//! Within the `extern "Rust"` part of the CXX bridge we list the types and 16733d722a9Sopenharmony_ci//! functions for which Rust is the source of truth. These all implicitly refer 16833d722a9Sopenharmony_ci//! to the `super` module, the parent module of the CXX bridge. You can think of 16933d722a9Sopenharmony_ci//! the two items listed in the example above as being like `use 17033d722a9Sopenharmony_ci//! super::MultiBuf` and `use super::next_chunk` except re-exported to C++. The 17133d722a9Sopenharmony_ci//! parent module will either contain the definitions directly for simple 17233d722a9Sopenharmony_ci//! things, or contain the relevant `use` statements to bring them into scope 17333d722a9Sopenharmony_ci//! from elsewhere. 17433d722a9Sopenharmony_ci//! 17533d722a9Sopenharmony_ci//! Within the `extern "C++"` part, we list types and functions for which C++ is 17633d722a9Sopenharmony_ci//! the source of truth, as well as the header(s) that declare those APIs. In 17733d722a9Sopenharmony_ci//! the future it's possible that this section could be generated bindgen-style 17833d722a9Sopenharmony_ci//! from the headers but for now we need the signatures written out; static 17933d722a9Sopenharmony_ci//! assertions will verify that they are accurate. 18033d722a9Sopenharmony_ci//! 18133d722a9Sopenharmony_ci//! Your function implementations themselves, whether in C++ or Rust, *do not* 18233d722a9Sopenharmony_ci//! need to be defined as `extern "C"` ABI or no\_mangle. CXX will put in the 18333d722a9Sopenharmony_ci//! right shims where necessary to make it all work. 18433d722a9Sopenharmony_ci//! 18533d722a9Sopenharmony_ci//! <br> 18633d722a9Sopenharmony_ci//! 18733d722a9Sopenharmony_ci//! # Comparison vs bindgen and cbindgen 18833d722a9Sopenharmony_ci//! 18933d722a9Sopenharmony_ci//! Notice that with CXX there is repetition of all the function signatures: 19033d722a9Sopenharmony_ci//! they are typed out once where the implementation is defined (in C++ or Rust) 19133d722a9Sopenharmony_ci//! and again inside the cxx::bridge module, though compile-time assertions 19233d722a9Sopenharmony_ci//! guarantee these are kept in sync. This is different from [bindgen] and 19333d722a9Sopenharmony_ci//! [cbindgen] where function signatures are typed by a human once and the tool 19433d722a9Sopenharmony_ci//! consumes them in one language and emits them in the other language. 19533d722a9Sopenharmony_ci//! 19633d722a9Sopenharmony_ci//! [bindgen]: https://github.com/rust-lang/rust-bindgen 19733d722a9Sopenharmony_ci//! [cbindgen]: https://github.com/eqrion/cbindgen/ 19833d722a9Sopenharmony_ci//! 19933d722a9Sopenharmony_ci//! This is because CXX fills a somewhat different role. It is a lower level 20033d722a9Sopenharmony_ci//! tool than bindgen or cbindgen in a sense; you can think of it as being a 20133d722a9Sopenharmony_ci//! replacement for the concept of `extern "C"` signatures as we know them, 20233d722a9Sopenharmony_ci//! rather than a replacement for a bindgen. It would be reasonable to build a 20333d722a9Sopenharmony_ci//! higher level bindgen-like tool on top of CXX which consumes a C++ header 20433d722a9Sopenharmony_ci//! and/or Rust module (and/or IDL like Thrift) as source of truth and generates 20533d722a9Sopenharmony_ci//! the cxx::bridge, eliminating the repetition while leveraging the static 20633d722a9Sopenharmony_ci//! analysis safety guarantees of CXX. 20733d722a9Sopenharmony_ci//! 20833d722a9Sopenharmony_ci//! But note in other ways CXX is higher level than the bindgens, with rich 20933d722a9Sopenharmony_ci//! support for common standard library types. Frequently with bindgen when we 21033d722a9Sopenharmony_ci//! are dealing with an idiomatic C++ API we would end up manually wrapping that 21133d722a9Sopenharmony_ci//! API in C-style raw pointer functions, applying bindgen to get unsafe raw 21233d722a9Sopenharmony_ci//! pointer Rust functions, and replicating the API again to expose those 21333d722a9Sopenharmony_ci//! idiomatically in Rust. That's a much worse form of repetition because it is 21433d722a9Sopenharmony_ci//! unsafe all the way through. 21533d722a9Sopenharmony_ci//! 21633d722a9Sopenharmony_ci//! By using a CXX bridge as the shared understanding between the languages, 21733d722a9Sopenharmony_ci//! rather than `extern "C"` C-style signatures as the shared understanding, 21833d722a9Sopenharmony_ci//! common FFI use cases become expressible using 100% safe code. 21933d722a9Sopenharmony_ci//! 22033d722a9Sopenharmony_ci//! It would also be reasonable to mix and match, using CXX bridge for the 95% 22133d722a9Sopenharmony_ci//! of your FFI that is straightforward and doing the remaining few oddball 22233d722a9Sopenharmony_ci//! signatures the old fashioned way with bindgen and cbindgen, if for some 22333d722a9Sopenharmony_ci//! reason CXX's static restrictions get in the way. Please file an issue if you 22433d722a9Sopenharmony_ci//! end up taking this approach so that we know what ways it would be worthwhile 22533d722a9Sopenharmony_ci//! to make the tool more expressive. 22633d722a9Sopenharmony_ci//! 22733d722a9Sopenharmony_ci//! <br> 22833d722a9Sopenharmony_ci//! 22933d722a9Sopenharmony_ci//! # Cargo-based setup 23033d722a9Sopenharmony_ci//! 23133d722a9Sopenharmony_ci//! For builds that are orchestrated by Cargo, you will use a build script that 23233d722a9Sopenharmony_ci//! runs CXX's C++ code generator and compiles the resulting C++ code along with 23333d722a9Sopenharmony_ci//! any other C++ code for your crate. 23433d722a9Sopenharmony_ci//! 23533d722a9Sopenharmony_ci//! The canonical build script is as follows. The indicated line returns a 23633d722a9Sopenharmony_ci//! [`cc::Build`] instance (from the usual widely used `cc` crate) on which you 23733d722a9Sopenharmony_ci//! can set up any additional source files and compiler flags as normal. 23833d722a9Sopenharmony_ci//! 23933d722a9Sopenharmony_ci//! [`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html 24033d722a9Sopenharmony_ci//! 24133d722a9Sopenharmony_ci//! ```toml 24233d722a9Sopenharmony_ci//! # Cargo.toml 24333d722a9Sopenharmony_ci//! 24433d722a9Sopenharmony_ci//! [build-dependencies] 24533d722a9Sopenharmony_ci//! cxx-build = "1.0" 24633d722a9Sopenharmony_ci//! ``` 24733d722a9Sopenharmony_ci//! 24833d722a9Sopenharmony_ci//! ```no_run 24933d722a9Sopenharmony_ci//! // build.rs 25033d722a9Sopenharmony_ci//! 25133d722a9Sopenharmony_ci//! fn main() { 25233d722a9Sopenharmony_ci//! cxx_build::bridge("src/main.rs") // returns a cc::Build 25333d722a9Sopenharmony_ci//! .file("src/demo.cc") 25433d722a9Sopenharmony_ci//! .flag_if_supported("-std=c++11") 25533d722a9Sopenharmony_ci//! .compile("cxxbridge-demo"); 25633d722a9Sopenharmony_ci//! 25733d722a9Sopenharmony_ci//! println!("cargo:rerun-if-changed=src/main.rs"); 25833d722a9Sopenharmony_ci//! println!("cargo:rerun-if-changed=src/demo.cc"); 25933d722a9Sopenharmony_ci//! println!("cargo:rerun-if-changed=include/demo.h"); 26033d722a9Sopenharmony_ci//! } 26133d722a9Sopenharmony_ci//! ``` 26233d722a9Sopenharmony_ci//! 26333d722a9Sopenharmony_ci//! <br><br> 26433d722a9Sopenharmony_ci//! 26533d722a9Sopenharmony_ci//! # Non-Cargo setup 26633d722a9Sopenharmony_ci//! 26733d722a9Sopenharmony_ci//! For use in non-Cargo builds like Bazel or Buck, CXX provides an alternate 26833d722a9Sopenharmony_ci//! way of invoking the C++ code generator as a standalone command line tool. 26933d722a9Sopenharmony_ci//! The tool is packaged as the `cxxbridge-cmd` crate on crates.io or can be 27033d722a9Sopenharmony_ci//! built from the *gen/cmd* directory of <https://github.com/dtolnay/cxx>. 27133d722a9Sopenharmony_ci//! 27233d722a9Sopenharmony_ci//! ```bash 27333d722a9Sopenharmony_ci//! $ cargo install cxxbridge-cmd 27433d722a9Sopenharmony_ci//! 27533d722a9Sopenharmony_ci//! $ cxxbridge src/main.rs --header > path/to/mybridge.h 27633d722a9Sopenharmony_ci//! $ cxxbridge src/main.rs > path/to/mybridge.cc 27733d722a9Sopenharmony_ci//! ``` 27833d722a9Sopenharmony_ci//! 27933d722a9Sopenharmony_ci//! <br> 28033d722a9Sopenharmony_ci//! 28133d722a9Sopenharmony_ci//! # Safety 28233d722a9Sopenharmony_ci//! 28333d722a9Sopenharmony_ci//! Be aware that the design of this library is intentionally restrictive and 28433d722a9Sopenharmony_ci//! opinionated! It isn't a goal to be powerful enough to handle arbitrary 28533d722a9Sopenharmony_ci//! signatures in either language. Instead this project is about carving out a 28633d722a9Sopenharmony_ci//! reasonably expressive set of functionality about which we can make useful 28733d722a9Sopenharmony_ci//! safety guarantees today and maybe extend over time. You may find that it 28833d722a9Sopenharmony_ci//! takes some practice to use CXX bridge effectively as it won't work in all 28933d722a9Sopenharmony_ci//! the ways that you are used to. 29033d722a9Sopenharmony_ci//! 29133d722a9Sopenharmony_ci//! Some of the considerations that go into ensuring safety are: 29233d722a9Sopenharmony_ci//! 29333d722a9Sopenharmony_ci//! - By design, our paired code generators work together to control both sides 29433d722a9Sopenharmony_ci//! of the FFI boundary. Ordinarily in Rust writing your own `extern "C"` 29533d722a9Sopenharmony_ci//! blocks is unsafe because the Rust compiler has no way to know whether the 29633d722a9Sopenharmony_ci//! signatures you've written actually match the signatures implemented in the 29733d722a9Sopenharmony_ci//! other language. With CXX we achieve that visibility and know what's on the 29833d722a9Sopenharmony_ci//! other side. 29933d722a9Sopenharmony_ci//! 30033d722a9Sopenharmony_ci//! - Our static analysis detects and prevents passing types by value that 30133d722a9Sopenharmony_ci//! shouldn't be passed by value from C++ to Rust, for example because they 30233d722a9Sopenharmony_ci//! may contain internal pointers that would be screwed up by Rust's move 30333d722a9Sopenharmony_ci//! behavior. 30433d722a9Sopenharmony_ci//! 30533d722a9Sopenharmony_ci//! - To many people's surprise, it is possible to have a struct in Rust and a 30633d722a9Sopenharmony_ci//! struct in C++ with exactly the same layout / fields / alignment / 30733d722a9Sopenharmony_ci//! everything, and still not the same ABI when passed by value. This is a 30833d722a9Sopenharmony_ci//! longstanding bindgen bug that leads to segfaults in absolutely 30933d722a9Sopenharmony_ci//! correct-looking code ([rust-lang/rust-bindgen#778]). CXX knows about this 31033d722a9Sopenharmony_ci//! and can insert the necessary zero-cost workaround transparently where 31133d722a9Sopenharmony_ci//! needed, so go ahead and pass your structs by value without worries. This 31233d722a9Sopenharmony_ci//! is made possible by owning both sides of the boundary rather than just 31333d722a9Sopenharmony_ci//! one. 31433d722a9Sopenharmony_ci//! 31533d722a9Sopenharmony_ci//! - Template instantiations: for example in order to expose a UniquePtr\<T\> 31633d722a9Sopenharmony_ci//! type in Rust backed by a real C++ unique\_ptr, we have a way of using a 31733d722a9Sopenharmony_ci//! Rust trait to connect the behavior back to the template instantiations 31833d722a9Sopenharmony_ci//! performed by the other language. 31933d722a9Sopenharmony_ci//! 32033d722a9Sopenharmony_ci//! [rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778 32133d722a9Sopenharmony_ci//! 32233d722a9Sopenharmony_ci//! <br> 32333d722a9Sopenharmony_ci//! 32433d722a9Sopenharmony_ci//! # Builtin types 32533d722a9Sopenharmony_ci//! 32633d722a9Sopenharmony_ci//! In addition to all the primitive types (i32 <=> int32_t), the 32733d722a9Sopenharmony_ci//! following common types may be used in the fields of shared structs and the 32833d722a9Sopenharmony_ci//! arguments and returns of functions. 32933d722a9Sopenharmony_ci//! 33033d722a9Sopenharmony_ci//! <table> 33133d722a9Sopenharmony_ci//! <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr> 33233d722a9Sopenharmony_ci//! <tr><td>String</td><td>rust::String</td><td></td></tr> 33333d722a9Sopenharmony_ci//! <tr><td>&str</td><td>rust::Str</td><td></td></tr> 33433d722a9Sopenharmony_ci//! <tr><td>&[T]</td><td>rust::Slice<const T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> 33533d722a9Sopenharmony_ci//! <tr><td>&mut [T]</td><td>rust::Slice<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> 33633d722a9Sopenharmony_ci//! <tr><td><a href="struct.CxxString.html">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr> 33733d722a9Sopenharmony_ci//! <tr><td>Box<T></td><td>rust::Box<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> 33833d722a9Sopenharmony_ci//! <tr><td><a href="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> 33933d722a9Sopenharmony_ci//! <tr><td><a href="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> 34033d722a9Sopenharmony_ci//! <tr><td>[T; N]</td><td>std::array<T, N></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> 34133d722a9Sopenharmony_ci//! <tr><td>Vec<T></td><td>rust::Vec<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> 34233d722a9Sopenharmony_ci//! <tr><td><a href="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> 34333d722a9Sopenharmony_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> 34433d722a9Sopenharmony_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> 34533d722a9Sopenharmony_ci//! <tr><td>Result<T></td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr> 34633d722a9Sopenharmony_ci//! </table> 34733d722a9Sopenharmony_ci//! 34833d722a9Sopenharmony_ci//! The C++ API of the `rust` namespace is defined by the *include/cxx.h* file 34933d722a9Sopenharmony_ci//! in <https://github.com/dtolnay/cxx>. You will need to include this header in 35033d722a9Sopenharmony_ci//! your C++ code when working with those types. 35133d722a9Sopenharmony_ci//! 35233d722a9Sopenharmony_ci//! The following types are intended to be supported "soon" but are just not 35333d722a9Sopenharmony_ci//! implemented yet. I don't expect any of these to be hard to make work but 35433d722a9Sopenharmony_ci//! it's a matter of designing a nice API for each in its non-native language. 35533d722a9Sopenharmony_ci//! 35633d722a9Sopenharmony_ci//! <table> 35733d722a9Sopenharmony_ci//! <tr><th>name in Rust</th><th>name in C++</th></tr> 35833d722a9Sopenharmony_ci//! <tr><td>BTreeMap<K, V></td><td><sup><i>tbd</i></sup></td></tr> 35933d722a9Sopenharmony_ci//! <tr><td>HashMap<K, V></td><td><sup><i>tbd</i></sup></td></tr> 36033d722a9Sopenharmony_ci//! <tr><td>Arc<T></td><td><sup><i>tbd</i></sup></td></tr> 36133d722a9Sopenharmony_ci//! <tr><td>Option<T></td><td><sup><i>tbd</i></sup></td></tr> 36233d722a9Sopenharmony_ci//! <tr><td><sup><i>tbd</i></sup></td><td>std::map<K, V></td></tr> 36333d722a9Sopenharmony_ci//! <tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map<K, V></td></tr> 36433d722a9Sopenharmony_ci//! </table> 36533d722a9Sopenharmony_ci 36633d722a9Sopenharmony_ci#![no_std] 36733d722a9Sopenharmony_ci#![doc(html_root_url = "https://docs.rs/cxx/1.0.97")] 36833d722a9Sopenharmony_ci#![deny( 36933d722a9Sopenharmony_ci improper_ctypes, 37033d722a9Sopenharmony_ci improper_ctypes_definitions, 37133d722a9Sopenharmony_ci missing_docs, 37233d722a9Sopenharmony_ci unsafe_op_in_unsafe_fn 37333d722a9Sopenharmony_ci)] 37433d722a9Sopenharmony_ci#![cfg_attr(doc_cfg, feature(doc_cfg))] 37533d722a9Sopenharmony_ci#![allow(non_camel_case_types)] 37633d722a9Sopenharmony_ci#![allow( 37733d722a9Sopenharmony_ci clippy::cognitive_complexity, 37833d722a9Sopenharmony_ci clippy::declare_interior_mutable_const, 37933d722a9Sopenharmony_ci clippy::doc_markdown, 38033d722a9Sopenharmony_ci clippy::empty_enum, 38133d722a9Sopenharmony_ci clippy::extra_unused_type_parameters, 38233d722a9Sopenharmony_ci clippy::inherent_to_string, 38333d722a9Sopenharmony_ci clippy::items_after_statements, 38433d722a9Sopenharmony_ci clippy::large_enum_variant, 38533d722a9Sopenharmony_ci clippy::len_without_is_empty, 38633d722a9Sopenharmony_ci clippy::missing_errors_doc, 38733d722a9Sopenharmony_ci clippy::missing_safety_doc, 38833d722a9Sopenharmony_ci clippy::module_inception, 38933d722a9Sopenharmony_ci clippy::module_name_repetitions, 39033d722a9Sopenharmony_ci clippy::must_use_candidate, 39133d722a9Sopenharmony_ci clippy::needless_doctest_main, 39233d722a9Sopenharmony_ci clippy::new_without_default, 39333d722a9Sopenharmony_ci clippy::or_fun_call, 39433d722a9Sopenharmony_ci clippy::ptr_arg, 39533d722a9Sopenharmony_ci clippy::toplevel_ref_arg, 39633d722a9Sopenharmony_ci clippy::transmute_undefined_repr, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8417 39733d722a9Sopenharmony_ci clippy::useless_let_if_seq, 39833d722a9Sopenharmony_ci clippy::wrong_self_convention 39933d722a9Sopenharmony_ci)] 40033d722a9Sopenharmony_ci 40133d722a9Sopenharmony_ci#[cfg(built_with_cargo)] 40233d722a9Sopenharmony_ciextern crate link_cplusplus; 40333d722a9Sopenharmony_ci 40433d722a9Sopenharmony_ciextern crate self as cxx; 40533d722a9Sopenharmony_ci 40633d722a9Sopenharmony_ci#[doc(hidden)] 40733d722a9Sopenharmony_cipub extern crate core; 40833d722a9Sopenharmony_ci 40933d722a9Sopenharmony_ci#[cfg(feature = "alloc")] 41033d722a9Sopenharmony_ci#[doc(hidden)] 41133d722a9Sopenharmony_cipub extern crate alloc; 41233d722a9Sopenharmony_ci 41333d722a9Sopenharmony_ci#[cfg(not(feature = "alloc"))] 41433d722a9Sopenharmony_ciextern crate core as alloc; 41533d722a9Sopenharmony_ci 41633d722a9Sopenharmony_ci#[cfg(feature = "std")] 41733d722a9Sopenharmony_ci#[doc(hidden)] 41833d722a9Sopenharmony_cipub extern crate std; 41933d722a9Sopenharmony_ci 42033d722a9Sopenharmony_ci// Block inadvertent use of items from libstd, which does not otherwise produce 42133d722a9Sopenharmony_ci// a compile-time error on edition 2018+. 42233d722a9Sopenharmony_ci#[cfg(not(feature = "std"))] 42333d722a9Sopenharmony_ciextern crate core as std; 42433d722a9Sopenharmony_ci 42533d722a9Sopenharmony_ci#[cfg(not(any(feature = "alloc", cxx_experimental_no_alloc)))] 42633d722a9Sopenharmony_cicompile_error! { 42733d722a9Sopenharmony_ci r#"cxx support for no_alloc is incomplete and semver exempt; you must build with at least one of feature="std", feature="alloc", or RUSTFLAGS='--cfg cxx_experimental_no_alloc'"# 42833d722a9Sopenharmony_ci} 42933d722a9Sopenharmony_ci 43033d722a9Sopenharmony_ci#[cfg(all(compile_error_if_alloc, feature = "alloc"))] 43133d722a9Sopenharmony_cicompile_error! { 43233d722a9Sopenharmony_ci r#"feature="alloc" is unexpectedly enabled"# 43333d722a9Sopenharmony_ci} 43433d722a9Sopenharmony_ci 43533d722a9Sopenharmony_ci#[cfg(all(compile_error_if_std, feature = "std"))] 43633d722a9Sopenharmony_cicompile_error! { 43733d722a9Sopenharmony_ci r#"feature="std" is unexpectedly enabled"# 43833d722a9Sopenharmony_ci} 43933d722a9Sopenharmony_ci 44033d722a9Sopenharmony_ci#[macro_use] 44133d722a9Sopenharmony_cimod macros; 44233d722a9Sopenharmony_ci 44333d722a9Sopenharmony_cimod c_char; 44433d722a9Sopenharmony_cimod cxx_vector; 44533d722a9Sopenharmony_cimod exception; 44633d722a9Sopenharmony_cimod extern_type; 44733d722a9Sopenharmony_cimod fmt; 44833d722a9Sopenharmony_cimod function; 44933d722a9Sopenharmony_cimod hash; 45033d722a9Sopenharmony_cimod lossy; 45133d722a9Sopenharmony_cipub mod memory; 45233d722a9Sopenharmony_cimod opaque; 45333d722a9Sopenharmony_cimod result; 45433d722a9Sopenharmony_cimod rust_slice; 45533d722a9Sopenharmony_cimod rust_str; 45633d722a9Sopenharmony_cimod rust_string; 45733d722a9Sopenharmony_cimod rust_type; 45833d722a9Sopenharmony_cimod rust_vec; 45933d722a9Sopenharmony_cimod shared_ptr; 46033d722a9Sopenharmony_cimod sip; 46133d722a9Sopenharmony_ci#[path = "cxx_string.rs"] 46233d722a9Sopenharmony_cimod string; 46333d722a9Sopenharmony_cimod symbols; 46433d722a9Sopenharmony_cimod type_id; 46533d722a9Sopenharmony_cimod unique_ptr; 46633d722a9Sopenharmony_cimod unwind; 46733d722a9Sopenharmony_cipub mod vector; 46833d722a9Sopenharmony_cimod weak_ptr; 46933d722a9Sopenharmony_ci 47033d722a9Sopenharmony_cipub use crate::cxx_vector::CxxVector; 47133d722a9Sopenharmony_ci#[cfg(feature = "alloc")] 47233d722a9Sopenharmony_cipub use crate::exception::Exception; 47333d722a9Sopenharmony_cipub use crate::extern_type::{kind, ExternType}; 47433d722a9Sopenharmony_cipub use crate::shared_ptr::SharedPtr; 47533d722a9Sopenharmony_cipub use crate::string::CxxString; 47633d722a9Sopenharmony_cipub use crate::unique_ptr::UniquePtr; 47733d722a9Sopenharmony_cipub use crate::weak_ptr::WeakPtr; 47833d722a9Sopenharmony_cipub use cxxbridge_macro::bridge; 47933d722a9Sopenharmony_ci 48033d722a9Sopenharmony_ci/// Synonym for `CxxString`. 48133d722a9Sopenharmony_ci/// 48233d722a9Sopenharmony_ci/// To avoid confusion with Rust's standard library string you probably 48333d722a9Sopenharmony_ci/// shouldn't import this type with `use`. Instead, write `cxx::String`, or 48433d722a9Sopenharmony_ci/// import and use `CxxString`. 48533d722a9Sopenharmony_cipub type String = CxxString; 48633d722a9Sopenharmony_ci 48733d722a9Sopenharmony_ci/// Synonym for `CxxVector`. 48833d722a9Sopenharmony_ci/// 48933d722a9Sopenharmony_ci/// To avoid confusion with Rust's standard library vector you probably 49033d722a9Sopenharmony_ci/// shouldn't import this type with `use`. Instead, write `cxx::Vector<T>`, or 49133d722a9Sopenharmony_ci/// import and use `CxxVector`. 49233d722a9Sopenharmony_cipub type Vector<T> = CxxVector<T>; 49333d722a9Sopenharmony_ci 49433d722a9Sopenharmony_ci// Not public API. 49533d722a9Sopenharmony_ci#[doc(hidden)] 49633d722a9Sopenharmony_cipub mod private { 49733d722a9Sopenharmony_ci pub use crate::c_char::c_char; 49833d722a9Sopenharmony_ci pub use crate::cxx_vector::VectorElement; 49933d722a9Sopenharmony_ci pub use crate::extern_type::{verify_extern_kind, verify_extern_type}; 50033d722a9Sopenharmony_ci pub use crate::function::FatFunction; 50133d722a9Sopenharmony_ci pub use crate::hash::hash; 50233d722a9Sopenharmony_ci pub use crate::opaque::Opaque; 50333d722a9Sopenharmony_ci #[cfg(feature = "alloc")] 50433d722a9Sopenharmony_ci pub use crate::result::{r#try, Result}; 50533d722a9Sopenharmony_ci pub use crate::rust_slice::RustSlice; 50633d722a9Sopenharmony_ci pub use crate::rust_str::RustStr; 50733d722a9Sopenharmony_ci #[cfg(feature = "alloc")] 50833d722a9Sopenharmony_ci pub use crate::rust_string::RustString; 50933d722a9Sopenharmony_ci pub use crate::rust_type::{ImplBox, ImplVec, RustType}; 51033d722a9Sopenharmony_ci #[cfg(feature = "alloc")] 51133d722a9Sopenharmony_ci pub use crate::rust_vec::RustVec; 51233d722a9Sopenharmony_ci pub use crate::shared_ptr::SharedPtrTarget; 51333d722a9Sopenharmony_ci pub use crate::string::StackString; 51433d722a9Sopenharmony_ci pub use crate::unique_ptr::UniquePtrTarget; 51533d722a9Sopenharmony_ci pub use crate::unwind::prevent_unwind; 51633d722a9Sopenharmony_ci pub use crate::weak_ptr::WeakPtrTarget; 51733d722a9Sopenharmony_ci pub use core::{concat, module_path}; 51833d722a9Sopenharmony_ci pub use cxxbridge_macro::type_id; 51933d722a9Sopenharmony_ci} 52033d722a9Sopenharmony_ci 52133d722a9Sopenharmony_cimod actually_private { 52233d722a9Sopenharmony_ci pub trait Private {} 52333d722a9Sopenharmony_ci} 52433d722a9Sopenharmony_ci 52533d722a9Sopenharmony_cimacro_rules! chars { 52633d722a9Sopenharmony_ci ($($ch:ident)*) => { 52733d722a9Sopenharmony_ci $( 52833d722a9Sopenharmony_ci #[doc(hidden)] 52933d722a9Sopenharmony_ci pub enum $ch {} 53033d722a9Sopenharmony_ci )* 53133d722a9Sopenharmony_ci }; 53233d722a9Sopenharmony_ci} 53333d722a9Sopenharmony_ci 53433d722a9Sopenharmony_cichars! { 53533d722a9Sopenharmony_ci _0 _1 _2 _3 _4 _5 _6 _7 _8 _9 53633d722a9Sopenharmony_ci A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 53733d722a9Sopenharmony_ci a b c d e f g h i j k l m n o p q r s t u v w x y z 53833d722a9Sopenharmony_ci __ // underscore 53933d722a9Sopenharmony_ci} 54033d722a9Sopenharmony_ci 54133d722a9Sopenharmony_ci#[repr(transparent)] 54233d722a9Sopenharmony_cistruct void(core::ffi::c_void); 543