| //! [![github]](https://github.com/dtolnay/cxx) [![crates-io]](https://crates.io/crates/cxx) [![docs-rs]](https://docs.rs/cxx) |
| //! |
| //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github |
| //! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust |
| //! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K |
| //! |
| //! <br> |
| //! |
| //! This library provides a **safe** mechanism for calling C++ code from Rust |
| //! and Rust code from C++, not subject to the many ways that things can go |
| //! wrong when using bindgen or cbindgen to generate unsafe C-style bindings. |
| //! |
| //! This doesn't change the fact that 100% of C++ code is unsafe. When auditing |
| //! a project, you would be on the hook for auditing all the unsafe Rust code |
| //! and *all* the C++ code. The core safety claim under this new model is that |
| //! auditing just the C++ side would be sufficient to catch all problems, i.e. |
| //! the Rust side can be 100% safe. |
| //! |
| //! <br> |
| //! |
| //! *Compiler support: requires rustc 1.48+ and c++11 or newer*<br> |
| //! *[Release notes](https://github.com/dtolnay/cxx/releases)* |
| //! |
| //! <br> |
| //! |
| //! # Guide |
| //! |
| //! Please see **<https://cxx.rs>** for a tutorial, reference material, and |
| //! example code. |
| //! |
| //! <br> |
| //! |
| //! # Overview |
| //! |
| //! The idea is that we define the signatures of both sides of our FFI boundary |
| //! embedded together in one Rust module (the next section shows an example). |
| //! From this, CXX receives a complete picture of the boundary to perform static |
| //! analyses against the types and function signatures to uphold both Rust's and |
| //! C++'s invariants and requirements. |
| //! |
| //! If everything checks out statically, then CXX uses a pair of code generators |
| //! to emit the relevant `extern "C"` signatures on both sides together with any |
| //! necessary static assertions for later in the build process to verify |
| //! correctness. On the Rust side this code generator is simply an attribute |
| //! procedural macro. On the C++ side it can be a small Cargo build script if |
| //! your build is managed by Cargo, or for other build systems like Bazel or |
| //! Buck we provide a command line tool which generates the header and source |
| //! file and should be easy to integrate. |
| //! |
| //! The resulting FFI bridge operates at zero or negligible overhead, i.e. no |
| //! copying, no serialization, no memory allocation, no runtime checks needed. |
| //! |
| //! The FFI signatures are able to use native types from whichever side they |
| //! please, such as Rust's `String` or C++'s `std::string`, Rust's `Box` or |
| //! C++'s `std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any |
| //! combination. CXX guarantees an ABI-compatible signature that both sides |
| //! understand, based on builtin bindings for key standard library types to |
| //! expose an idiomatic API on those types to the other language. For example |
| //! when manipulating a C++ string from Rust, its `len()` method becomes a call |
| //! of the `size()` member function defined by C++; when manipulation a Rust |
| //! string from C++, its `size()` member function calls Rust's `len()`. |
| //! |
| //! <br> |
| //! |
| //! # Example |
| //! |
| //! In this example we are writing a Rust application that wishes to take |
| //! advantage of an existing C++ client for a large-file blobstore service. The |
| //! blobstore supports a `put` operation for a discontiguous buffer upload. For |
| //! example we might be uploading snapshots of a circular buffer which would |
| //! tend to consist of 2 chunks, or fragments of a file spread across memory for |
| //! some other reason. |
| //! |
| //! A runnable version of this example is provided under the *demo* directory of |
| //! <https://github.com/dtolnay/cxx>. To try it out, run `cargo run` from that |
| //! directory. |
| //! |
| //! ```no_run |
| //! #[cxx::bridge] |
| //! mod ffi { |
| //! // Any shared structs, whose fields will be visible to both languages. |
| //! struct BlobMetadata { |
| //! size: usize, |
| //! tags: Vec<String>, |
| //! } |
| //! |
| //! extern "Rust" { |
| //! // Zero or more opaque types which both languages can pass around but |
| //! // only Rust can see the fields. |
| //! type MultiBuf; |
| //! |
| //! // Functions implemented in Rust. |
| //! fn next_chunk(buf: &mut MultiBuf) -> &[u8]; |
| //! } |
| //! |
| //! unsafe extern "C++" { |
| //! // One or more headers with the matching C++ declarations. Our code |
| //! // generators don't read it but it gets #include'd and used in static |
| //! // assertions to ensure our picture of the FFI boundary is accurate. |
| //! include!("demo/include/blobstore.h"); |
| //! |
| //! // Zero or more opaque types which both languages can pass around but |
| //! // only C++ can see the fields. |
| //! type BlobstoreClient; |
| //! |
| //! // Functions implemented in C++. |
| //! fn new_blobstore_client() -> UniquePtr<BlobstoreClient>; |
| //! fn put(&self, parts: &mut MultiBuf) -> u64; |
| //! fn tag(&self, blobid: u64, tag: &str); |
| //! fn metadata(&self, blobid: u64) -> BlobMetadata; |
| //! } |
| //! } |
| //! # |
| //! # pub struct MultiBuf; |
| //! # |
| //! # fn next_chunk(_buf: &mut MultiBuf) -> &[u8] { |
| //! # unimplemented!() |
| //! # } |
| //! # |
| //! # fn main() {} |
| //! ``` |
| //! |
| //! Now we simply provide Rust definitions of all the things in the `extern |
| //! "Rust"` block and C++ definitions of all the things in the `extern "C++"` |
| //! block, and get to call back and forth safely. |
| //! |
| //! Here are links to the complete set of source files involved in the demo: |
| //! |
| //! - [demo/src/main.rs](https://github.com/dtolnay/cxx/blob/master/demo/src/main.rs) |
| //! - [demo/build.rs](https://github.com/dtolnay/cxx/blob/master/demo/build.rs) |
| //! - [demo/include/blobstore.h](https://github.com/dtolnay/cxx/blob/master/demo/include/blobstore.h) |
| //! - [demo/src/blobstore.cc](https://github.com/dtolnay/cxx/blob/master/demo/src/blobstore.cc) |
| //! |
| //! To look at the code generated in both languages for the example by the CXX |
| //! code generators: |
| //! |
| //! ```console |
| //! # run Rust code generator and print to stdout |
| //! # (requires https://github.com/dtolnay/cargo-expand) |
| //! $ cargo expand --manifest-path demo/Cargo.toml |
| //! |
| //! # run C++ code generator and print to stdout |
| //! $ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs |
| //! ``` |
| //! |
| //! <br> |
| //! |
| //! # Details |
| //! |
| //! As seen in the example, the language of the FFI boundary involves 3 kinds of |
| //! items: |
| //! |
| //! - **Shared structs** — their fields are made visible to both |
| //! languages. The definition written within cxx::bridge is the single source |
| //! of truth. |
| //! |
| //! - **Opaque types** — their fields are secret from the other language. |
| //! These cannot be passed across the FFI by value but only behind an |
| //! indirection, such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can |
| //! be a type alias for an arbitrarily complicated generic language-specific |
| //! type depending on your use case. |
| //! |
| //! - **Functions** — implemented in either language, callable from the |
| //! other language. |
| //! |
| //! Within the `extern "Rust"` part of the CXX bridge we list the types and |
| //! functions for which Rust is the source of truth. These all implicitly refer |
| //! to the `super` module, the parent module of the CXX bridge. You can think of |
| //! the two items listed in the example above as being like `use |
| //! super::MultiBuf` and `use super::next_chunk` except re-exported to C++. The |
| //! parent module will either contain the definitions directly for simple |
| //! things, or contain the relevant `use` statements to bring them into scope |
| //! from elsewhere. |
| //! |
| //! Within the `extern "C++"` part, we list types and functions for which C++ is |
| //! the source of truth, as well as the header(s) that declare those APIs. In |
| //! the future it's possible that this section could be generated bindgen-style |
| //! from the headers but for now we need the signatures written out; static |
| //! assertions will verify that they are accurate. |
| //! |
| //! Your function implementations themselves, whether in C++ or Rust, *do not* |
| //! need to be defined as `extern "C"` ABI or no\_mangle. CXX will put in the |
| //! right shims where necessary to make it all work. |
| //! |
| //! <br> |
| //! |
| //! # Comparison vs bindgen and cbindgen |
| //! |
| //! Notice that with CXX there is repetition of all the function signatures: |
| //! they are typed out once where the implementation is defined (in C++ or Rust) |
| //! and again inside the cxx::bridge module, though compile-time assertions |
| //! guarantee these are kept in sync. This is different from [bindgen] and |
| //! [cbindgen] where function signatures are typed by a human once and the tool |
| //! consumes them in one language and emits them in the other language. |
| //! |
| //! [bindgen]: https://github.com/rust-lang/rust-bindgen |
| //! [cbindgen]: https://github.com/eqrion/cbindgen/ |
| //! |
| //! This is because CXX fills a somewhat different role. It is a lower level |
| //! tool than bindgen or cbindgen in a sense; you can think of it as being a |
| //! replacement for the concept of `extern "C"` signatures as we know them, |
| //! rather than a replacement for a bindgen. It would be reasonable to build a |
| //! higher level bindgen-like tool on top of CXX which consumes a C++ header |
| //! and/or Rust module (and/or IDL like Thrift) as source of truth and generates |
| //! the cxx::bridge, eliminating the repetition while leveraging the static |
| //! analysis safety guarantees of CXX. |
| //! |
| //! But note in other ways CXX is higher level than the bindgens, with rich |
| //! support for common standard library types. Frequently with bindgen when we |
| //! are dealing with an idiomatic C++ API we would end up manually wrapping that |
| //! API in C-style raw pointer functions, applying bindgen to get unsafe raw |
| //! pointer Rust functions, and replicating the API again to expose those |
| //! idiomatically in Rust. That's a much worse form of repetition because it is |
| //! unsafe all the way through. |
| //! |
| //! By using a CXX bridge as the shared understanding between the languages, |
| //! rather than `extern "C"` C-style signatures as the shared understanding, |
| //! common FFI use cases become expressible using 100% safe code. |
| //! |
| //! It would also be reasonable to mix and match, using CXX bridge for the 95% |
| //! of your FFI that is straightforward and doing the remaining few oddball |
| //! signatures the old fashioned way with bindgen and cbindgen, if for some |
| //! reason CXX's static restrictions get in the way. Please file an issue if you |
| //! end up taking this approach so that we know what ways it would be worthwhile |
| //! to make the tool more expressive. |
| //! |
| //! <br> |
| //! |
| //! # Cargo-based setup |
| //! |
| //! For builds that are orchestrated by Cargo, you will use a build script that |
| //! runs CXX's C++ code generator and compiles the resulting C++ code along with |
| //! any other C++ code for your crate. |
| //! |
| //! The canonical build script is as follows. The indicated line returns a |
| //! [`cc::Build`] instance (from the usual widely used `cc` crate) on which you |
| //! can set up any additional source files and compiler flags as normal. |
| //! |
| //! [`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html |
| //! |
| //! ```toml |
| //! # Cargo.toml |
| //! |
| //! [build-dependencies] |
| //! cxx-build = "1.0" |
| //! ``` |
| //! |
| //! ```no_run |
| //! // build.rs |
| //! |
| //! fn main() { |
| //! cxx_build::bridge("src/main.rs") // returns a cc::Build |
| //! .file("src/demo.cc") |
| //! .flag_if_supported("-std=c++11") |
| //! .compile("cxxbridge-demo"); |
| //! |
| //! println!("cargo:rerun-if-changed=src/main.rs"); |
| //! println!("cargo:rerun-if-changed=src/demo.cc"); |
| //! println!("cargo:rerun-if-changed=include/demo.h"); |
| //! } |
| //! ``` |
| //! |
| //! <br><br> |
| //! |
| //! # Non-Cargo setup |
| //! |
| //! For use in non-Cargo builds like Bazel or Buck, CXX provides an alternate |
| //! way of invoking the C++ code generator as a standalone command line tool. |
| //! The tool is packaged as the `cxxbridge-cmd` crate on crates.io or can be |
| //! built from the *gen/cmd* directory of <https://github.com/dtolnay/cxx>. |
| //! |
| //! ```bash |
| //! $ cargo install cxxbridge-cmd |
| //! |
| //! $ cxxbridge src/main.rs --header > path/to/mybridge.h |
| //! $ cxxbridge src/main.rs > path/to/mybridge.cc |
| //! ``` |
| //! |
| //! <br> |
| //! |
| //! # Safety |
| //! |
| //! Be aware that the design of this library is intentionally restrictive and |
| //! opinionated! It isn't a goal to be powerful enough to handle arbitrary |
| //! signatures in either language. Instead this project is about carving out a |
| //! reasonably expressive set of functionality about which we can make useful |
| //! safety guarantees today and maybe extend over time. You may find that it |
| //! takes some practice to use CXX bridge effectively as it won't work in all |
| //! the ways that you are used to. |
| //! |
| //! Some of the considerations that go into ensuring safety are: |
| //! |
| //! - By design, our paired code generators work together to control both sides |
| //! of the FFI boundary. Ordinarily in Rust writing your own `extern "C"` |
| //! blocks is unsafe because the Rust compiler has no way to know whether the |
| //! signatures you've written actually match the signatures implemented in the |
| //! other language. With CXX we achieve that visibility and know what's on the |
| //! other side. |
| //! |
| //! - Our static analysis detects and prevents passing types by value that |
| //! shouldn't be passed by value from C++ to Rust, for example because they |
| //! may contain internal pointers that would be screwed up by Rust's move |
| //! behavior. |
| //! |
| //! - To many people's surprise, it is possible to have a struct in Rust and a |
| //! struct in C++ with exactly the same layout / fields / alignment / |
| //! everything, and still not the same ABI when passed by value. This is a |
| //! longstanding bindgen bug that leads to segfaults in absolutely |
| //! correct-looking code ([rust-lang/rust-bindgen#778]). CXX knows about this |
| //! and can insert the necessary zero-cost workaround transparently where |
| //! needed, so go ahead and pass your structs by value without worries. This |
| //! is made possible by owning both sides of the boundary rather than just |
| //! one. |
| //! |
| //! - Template instantiations: for example in order to expose a UniquePtr\<T\> |
| //! type in Rust backed by a real C++ unique\_ptr, we have a way of using a |
| //! Rust trait to connect the behavior back to the template instantiations |
| //! performed by the other language. |
| //! |
| //! [rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778 |
| //! |
| //! <br> |
| //! |
| //! # Builtin types |
| //! |
| //! In addition to all the primitive types (i32 <=> int32_t), the |
| //! following common types may be used in the fields of shared structs and the |
| //! arguments and returns of functions. |
| //! |
| //! <table> |
| //! <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr> |
| //! <tr><td>String</td><td>rust::String</td><td></td></tr> |
| //! <tr><td>&str</td><td>rust::Str</td><td></td></tr> |
| //! <tr><td>&[T]</td><td>rust::Slice<const T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> |
| //! <tr><td>&mut [T]</td><td>rust::Slice<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> |
| //! <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> |
| //! <tr><td>Box<T></td><td>rust::Box<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> |
| //! <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> |
| //! <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> |
| //! <tr><td>[T; N]</td><td>std::array<T, N></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> |
| //! <tr><td>Vec<T></td><td>rust::Vec<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> |
| //! <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> |
| //! <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> |
| //! <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> |
| //! <tr><td>Result<T></td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr> |
| //! </table> |
| //! |
| //! The C++ API of the `rust` namespace is defined by the *include/cxx.h* file |
| //! in <https://github.com/dtolnay/cxx>. You will need to include this header in |
| //! your C++ code when working with those types. |
| //! |
| //! The following types are intended to be supported "soon" but are just not |
| //! implemented yet. I don't expect any of these to be hard to make work but |
| //! it's a matter of designing a nice API for each in its non-native language. |
| //! |
| //! <table> |
| //! <tr><th>name in Rust</th><th>name in C++</th></tr> |
| //! <tr><td>BTreeMap<K, V></td><td><sup><i>tbd</i></sup></td></tr> |
| //! <tr><td>HashMap<K, V></td><td><sup><i>tbd</i></sup></td></tr> |
| //! <tr><td>Arc<T></td><td><sup><i>tbd</i></sup></td></tr> |
| //! <tr><td>Option<T></td><td><sup><i>tbd</i></sup></td></tr> |
| //! <tr><td><sup><i>tbd</i></sup></td><td>std::map<K, V></td></tr> |
| //! <tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map<K, V></td></tr> |
| //! </table> |
| |
| #![no_std] |
| #![doc(html_root_url = "https://docs.rs/cxx/1.0.66")] |
| #![deny(improper_ctypes, improper_ctypes_definitions, missing_docs)] |
| #![cfg_attr(not(no_unsafe_op_in_unsafe_fn_lint), deny(unsafe_op_in_unsafe_fn))] |
| #![cfg_attr(no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))] |
| #![cfg_attr(doc_cfg, feature(doc_cfg))] |
| #![allow(non_camel_case_types)] |
| #![allow( |
| clippy::cognitive_complexity, |
| clippy::declare_interior_mutable_const, |
| clippy::doc_markdown, |
| clippy::empty_enum, |
| clippy::inherent_to_string, |
| clippy::items_after_statements, |
| clippy::large_enum_variant, |
| clippy::len_without_is_empty, |
| clippy::missing_errors_doc, |
| clippy::missing_safety_doc, |
| clippy::module_inception, |
| clippy::module_name_repetitions, |
| clippy::must_use_candidate, |
| clippy::needless_doctest_main, |
| clippy::new_without_default, |
| clippy::or_fun_call, |
| clippy::ptr_arg, |
| clippy::toplevel_ref_arg, |
| clippy::transmute_undefined_repr, // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8417 |
| clippy::useless_let_if_seq, |
| clippy::wrong_self_convention |
| )] |
| |
| #[cfg(built_with_cargo)] |
| extern crate link_cplusplus; |
| |
| extern crate self as cxx; |
| |
| #[doc(hidden)] |
| pub extern crate core; |
| |
| #[cfg(feature = "alloc")] |
| #[doc(hidden)] |
| pub extern crate alloc; |
| |
| #[cfg(not(feature = "alloc"))] |
| extern crate core as alloc; |
| |
| #[cfg(feature = "std")] |
| #[doc(hidden)] |
| pub extern crate std; |
| |
| // Block inadvertent use of items from libstd, which does not otherwise produce |
| // a compile-time error on edition 2018+. |
| #[cfg(not(feature = "std"))] |
| extern crate core as std; |
| |
| #[cfg(not(any(feature = "alloc", cxx_experimental_no_alloc)))] |
| compile_error! { |
| 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'"# |
| } |
| |
| #[cfg(all(compile_error_if_alloc, feature = "alloc"))] |
| compile_error! { |
| r#"feature="alloc" is unexpectedly enabled"# |
| } |
| |
| #[cfg(all(compile_error_if_std, feature = "std"))] |
| compile_error! { |
| r#"feature="std" is unexpectedly enabled"# |
| } |
| |
| #[macro_use] |
| mod macros; |
| |
| mod c_char; |
| mod cxx_vector; |
| mod exception; |
| mod extern_type; |
| mod fmt; |
| mod function; |
| mod hash; |
| mod lossy; |
| pub mod memory; |
| mod opaque; |
| mod result; |
| mod rust_slice; |
| mod rust_str; |
| mod rust_string; |
| mod rust_type; |
| mod rust_vec; |
| mod shared_ptr; |
| mod sip; |
| #[path = "cxx_string.rs"] |
| mod string; |
| mod symbols; |
| mod type_id; |
| mod unique_ptr; |
| mod unwind; |
| pub mod vector; |
| mod weak_ptr; |
| |
| pub use crate::cxx_vector::CxxVector; |
| #[cfg(feature = "alloc")] |
| pub use crate::exception::Exception; |
| pub use crate::extern_type::{kind, ExternType}; |
| pub use crate::shared_ptr::SharedPtr; |
| pub use crate::string::CxxString; |
| pub use crate::unique_ptr::UniquePtr; |
| pub use crate::weak_ptr::WeakPtr; |
| pub use cxxbridge_macro::bridge; |
| |
| /// Synonym for `CxxString`. |
| /// |
| /// To avoid confusion with Rust's standard library string you probably |
| /// shouldn't import this type with `use`. Instead, write `cxx::String`, or |
| /// import and use `CxxString`. |
| pub type String = CxxString; |
| |
| /// Synonym for `CxxVector`. |
| /// |
| /// To avoid confusion with Rust's standard library vector you probably |
| /// shouldn't import this type with `use`. Instead, write `cxx::Vector<T>`, or |
| /// import and use `CxxVector`. |
| pub type Vector<T> = CxxVector<T>; |
| |
| // Not public API. |
| #[doc(hidden)] |
| pub mod private { |
| pub use crate::cxx_vector::VectorElement; |
| pub use crate::extern_type::{verify_extern_kind, verify_extern_type}; |
| pub use crate::function::FatFunction; |
| pub use crate::hash::hash; |
| pub use crate::opaque::Opaque; |
| #[cfg(feature = "alloc")] |
| pub use crate::result::{r#try, Result}; |
| pub use crate::rust_slice::RustSlice; |
| pub use crate::rust_str::RustStr; |
| #[cfg(feature = "alloc")] |
| pub use crate::rust_string::RustString; |
| pub use crate::rust_type::{ImplBox, ImplVec, RustType}; |
| #[cfg(feature = "alloc")] |
| pub use crate::rust_vec::RustVec; |
| pub use crate::shared_ptr::SharedPtrTarget; |
| pub use crate::string::StackString; |
| pub use crate::unique_ptr::UniquePtrTarget; |
| pub use crate::unwind::prevent_unwind; |
| pub use crate::weak_ptr::WeakPtrTarget; |
| pub use core::{concat, module_path}; |
| pub use cxxbridge_macro::type_id; |
| } |
| |
| mod actually_private { |
| pub trait Private {} |
| } |
| |
| macro_rules! chars { |
| ($($ch:ident)*) => { |
| $( |
| #[doc(hidden)] |
| pub enum $ch {} |
| )* |
| }; |
| } |
| |
| chars! { |
| _0 _1 _2 _3 _4 _5 _6 _7 _8 _9 |
| 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 |
| 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 |
| __ // underscore |
| } |
| |
| #[repr(transparent)] |
| struct void(core::ffi::c_void); |