| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 1 | CXX — safe FFI between Rust and C++ |
| 2 | ========================================= |
| 3 | |
| David Tolnay | dd3af09 | 2020-05-12 21:47:06 -0700 | [diff] [blame] | 4 | [<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) |
| 5 | [<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) |
| 6 | [<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-cxx-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/cxx) |
| 7 | [<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/cxx/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/cxx/actions?query=branch%3Amaster) |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 8 | |
| 9 | This library provides a **safe** mechanism for calling C++ code from Rust and |
| 10 | Rust code from C++, not subject to the many ways that things can go wrong when |
| 11 | using bindgen or cbindgen to generate unsafe C-style bindings. |
| 12 | |
| David Tolnay | ccd3975 | 2020-01-08 09:33:51 -0800 | [diff] [blame] | 13 | This doesn't change the fact that 100% of C++ code is unsafe. When auditing a |
| 14 | project, you would be on the hook for auditing all the unsafe Rust code and |
| 15 | *all* the C++ code. The core safety claim under this new model is that auditing |
| 16 | just the C++ side would be sufficient to catch all problems, i.e. the Rust side |
| 17 | can be 100% safe. |
| 18 | |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 19 | ```toml |
| 20 | [dependencies] |
| David Tolnay | 5f3fb89 | 2020-09-01 23:02:57 -0700 | [diff] [blame] | 21 | cxx = "0.4" |
| David Tolnay | c5cd7a1 | 2020-09-03 15:32:34 -0700 | [diff] [blame^] | 22 | |
| 23 | [build-dependencies] |
| 24 | cxx-build = "0.4" |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 25 | ``` |
| 26 | |
| David Tolnay | cf22385 | 2020-05-11 20:50:59 -0700 | [diff] [blame] | 27 | *Compiler support: requires rustc 1.42+ and c++11 or newer*<br> |
| David Tolnay | 5d08baa | 2020-04-27 18:12:08 -0700 | [diff] [blame] | 28 | *[Release notes](https://github.com/dtolnay/cxx/releases)* |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 29 | |
| 30 | <br> |
| 31 | |
| 32 | ## Overview |
| 33 | |
| 34 | The idea is that we define the signatures of both sides of our FFI boundary |
| 35 | embedded together in one Rust module (the next section shows an example). From |
| 36 | this, CXX receives a complete picture of the boundary to perform static analyses |
| 37 | against the types and function signatures to uphold both Rust's and C++'s |
| 38 | invariants and requirements. |
| 39 | |
| 40 | If everything checks out statically, then CXX uses a pair of code generators to |
| 41 | emit the relevant `extern "C"` signatures on both sides together with any |
| 42 | necessary static assertions for later in the build process to verify |
| 43 | correctness. On the Rust side this code generator is simply an attribute |
| 44 | procedural macro. On the C++ side it can be a small Cargo build script if your |
| 45 | build is managed by Cargo, or for other build systems like Bazel or Buck we |
| 46 | provide a command line tool which generates the header and source file and |
| 47 | should be easy to integrate. |
| 48 | |
| 49 | The resulting FFI bridge operates at zero or negligible overhead, i.e. no |
| 50 | copying, no serialization, no memory allocation, no runtime checks needed. |
| 51 | |
| 52 | The FFI signatures are able to use native types from whichever side they please, |
| 53 | such as Rust's `String` or C++'s `std::string`, Rust's `Box` or C++'s |
| 54 | `std::unique_ptr`, Rust's `Vec` or C++'s `std::vector`, etc in any combination. |
| 55 | CXX guarantees an ABI-compatible signature that both sides understand, based on |
| 56 | builtin bindings for key standard library types to expose an idiomatic API on |
| 57 | those types to the other language. For example when manipulating a C++ string |
| 58 | from Rust, its `len()` method becomes a call of the `size()` member function |
| Christopher Durham | b8d211d | 2020-05-24 11:56:32 -0400 | [diff] [blame] | 59 | defined by C++; when manipulating a Rust string from C++, its `size()` member |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 60 | function calls Rust's `len()`. |
| 61 | |
| 62 | <br> |
| 63 | |
| 64 | ## Example |
| 65 | |
| David Tolnay | 278f6fc | 2020-09-01 16:16:57 -0700 | [diff] [blame] | 66 | A runnable version of this example is provided under the *demo* directory of |
| 67 | this repo. To try it out, run `cargo run` from that directory. |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 68 | |
| 69 | ```rust |
| 70 | #[cxx::bridge] |
| 71 | mod ffi { |
| 72 | // Any shared structs, whose fields will be visible to both languages. |
| 73 | struct SharedThing { |
| 74 | z: i32, |
| 75 | y: Box<ThingR>, |
| 76 | x: UniquePtr<ThingC>, |
| 77 | } |
| 78 | |
| 79 | extern "C" { |
| 80 | // One or more headers with the matching C++ declarations. Our code |
| 81 | // generators don't read it but it gets #include'd and used in static |
| 82 | // assertions to ensure our picture of the FFI boundary is accurate. |
| David Tolnay | 278f6fc | 2020-09-01 16:16:57 -0700 | [diff] [blame] | 83 | include!("demo/include/demo.h"); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 84 | |
| 85 | // Zero or more opaque types which both languages can pass around but |
| 86 | // only C++ can see the fields. |
| 87 | type ThingC; |
| 88 | |
| 89 | // Functions implemented in C++. |
| 90 | fn make_demo(appname: &str) -> UniquePtr<ThingC>; |
| David Tolnay | b6a5f67 | 2020-04-17 15:04:56 -0700 | [diff] [blame] | 91 | fn get_name(thing: &ThingC) -> &CxxString; |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 92 | fn do_thing(state: SharedThing); |
| 93 | } |
| 94 | |
| 95 | extern "Rust" { |
| 96 | // Zero or more opaque types which both languages can pass around but |
| 97 | // only Rust can see the fields. |
| 98 | type ThingR; |
| 99 | |
| 100 | // Functions implemented in Rust. |
| 101 | fn print_r(r: &ThingR); |
| 102 | } |
| 103 | } |
| 104 | ``` |
| 105 | |
| 106 | Now we simply provide C++ definitions of all the things in the `extern "C"` |
| 107 | block and Rust definitions of all the things in the `extern "Rust"` block, and |
| 108 | get to call back and forth safely. |
| 109 | |
| 110 | Here are links to the complete set of source files involved in the demo: |
| 111 | |
| David Tolnay | 278f6fc | 2020-09-01 16:16:57 -0700 | [diff] [blame] | 112 | - [demo/src/main.rs](demo/src/main.rs) |
| 113 | - [demo/build.rs](demo/build.rs) |
| 114 | - [demo/include/demo.h](demo/include/demo.h) |
| 115 | - [demo/src/demo.cc](demo/src/demo.cc) |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 116 | |
| 117 | To look at the code generated in both languages for the example by the CXX code |
| 118 | generators: |
| 119 | |
| 120 | ```console |
| 121 | # run Rust code generator and print to stdout |
| 122 | # (requires https://github.com/dtolnay/cargo-expand) |
| David Tolnay | 278f6fc | 2020-09-01 16:16:57 -0700 | [diff] [blame] | 123 | $ cargo expand --manifest-path demo/Cargo.toml |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 124 | |
| 125 | # run C++ code generator and print to stdout |
| David Tolnay | 278f6fc | 2020-09-01 16:16:57 -0700 | [diff] [blame] | 126 | $ cargo run --manifest-path gen/cmd/Cargo.toml -- demo/src/main.rs |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 127 | ``` |
| 128 | |
| 129 | <br> |
| 130 | |
| 131 | ## Details |
| 132 | |
| 133 | As seen in the example, the language of the FFI boundary involves 3 kinds of |
| 134 | items: |
| 135 | |
| 136 | - **Shared structs** — their fields are made visible to both languages. |
| 137 | The definition written within cxx::bridge is the single source of truth. |
| 138 | |
| 139 | - **Opaque types** — their fields are secret from the other language. |
| 140 | These cannot be passed across the FFI by value but only behind an indirection, |
| 141 | such as a reference `&`, a Rust `Box`, or a `UniquePtr`. Can be a type alias |
| 142 | for an arbitrarily complicated generic language-specific type depending on |
| 143 | your use case. |
| 144 | |
| 145 | - **Functions** — implemented in either language, callable from the other |
| 146 | language. |
| 147 | |
| 148 | Within the `extern "C"` part of the CXX bridge we list the types and functions |
| 149 | for which C++ is the source of truth, as well as the header(s) that declare |
| 150 | those APIs. In the future it's possible that this section could be generated |
| 151 | bindgen-style from the headers but for now we need the signatures written out; |
| 152 | static assertions will verify that they are accurate. |
| 153 | |
| 154 | Within the `extern "Rust"` part, we list types and functions for which Rust is |
| 155 | the source of truth. These all implicitly refer to the `super` module, the |
| 156 | parent module of the CXX bridge. You can think of the two items listed in the |
| 157 | example above as being like `use super::ThingR` and `use super::print_r` except |
| 158 | re-exported to C++. The parent module will either contain the definitions |
| 159 | directly for simple things, or contain the relevant `use` statements to bring |
| 160 | them into scope from elsewhere. |
| 161 | |
| 162 | Your function implementations themselves, whether in C++ or Rust, *do not* need |
| 163 | to be defined as `extern "C"` ABI or no\_mangle. CXX will put in the right shims |
| 164 | where necessary to make it all work. |
| 165 | |
| 166 | <br> |
| 167 | |
| 168 | ## Comparison vs bindgen and cbindgen |
| 169 | |
| 170 | Notice that with CXX there is repetition of all the function signatures: they |
| 171 | are typed out once where the implementation is defined (in C++ or Rust) and |
| 172 | again inside the cxx::bridge module, though compile-time assertions guarantee |
| 173 | these are kept in sync. This is different from [bindgen] and [cbindgen] where |
| 174 | function signatures are typed by a human once and the tool consumes them in one |
| 175 | language and emits them in the other language. |
| 176 | |
| 177 | [bindgen]: https://github.com/rust-lang/rust-bindgen |
| 178 | [cbindgen]: https://github.com/eqrion/cbindgen/ |
| 179 | |
| 180 | This is because CXX fills a somewhat different role. It is a lower level tool |
| 181 | than bindgen or cbindgen in a sense; you can think of it as being a replacement |
| 182 | for the concept of `extern "C"` signatures as we know them, rather than a |
| 183 | replacement for a bindgen. It would be reasonable to build a higher level |
| 184 | bindgen-like tool on top of CXX which consumes a C++ header and/or Rust module |
| 185 | (and/or IDL like Thrift) as source of truth and generates the cxx::bridge, |
| 186 | eliminating the repetition while leveraging the static analysis safety |
| 187 | guarantees of CXX. |
| 188 | |
| 189 | But note in other ways CXX is higher level than the bindgens, with rich support |
| 190 | for common standard library types. Frequently with bindgen when we are dealing |
| 191 | with an idiomatic C++ API we would end up manually wrapping that API in C-style |
| 192 | raw pointer functions, applying bindgen to get unsafe raw pointer Rust |
| 193 | functions, and replicating the API again to expose those idiomatically in Rust. |
| 194 | That's a much worse form of repetition because it is unsafe all the way through. |
| 195 | |
| 196 | By using a CXX bridge as the shared understanding between the languages, rather |
| 197 | than `extern "C"` C-style signatures as the shared understanding, common FFI use |
| 198 | cases become expressible using 100% safe code. |
| 199 | |
| 200 | It would also be reasonable to mix and match, using CXX bridge for the 95% of |
| 201 | your FFI that is straightforward and doing the remaining few oddball signatures |
| 202 | the old fashioned way with bindgen and cbindgen, if for some reason CXX's static |
| 203 | restrictions get in the way. Please file an issue if you end up taking this |
| 204 | approach so that we know what ways it would be worthwhile to make the tool more |
| 205 | expressive. |
| 206 | |
| 207 | <br> |
| 208 | |
| 209 | ## Cargo-based setup |
| 210 | |
| 211 | For builds that are orchestrated by Cargo, you will use a build script that runs |
| 212 | CXX's C++ code generator and compiles the resulting C++ code along with any |
| 213 | other C++ code for your crate. |
| 214 | |
| 215 | The canonical build script is as follows. The indicated line returns a |
| 216 | [`cc::Build`] instance (from the usual widely used `cc` crate) on which you can |
| 217 | set up any additional source files and compiler flags as normal. |
| 218 | |
| 219 | [`cc::Build`]: https://docs.rs/cc/1.0/cc/struct.Build.html |
| 220 | |
| David Tolnay | cc9ece5 | 2020-04-29 18:57:05 -0700 | [diff] [blame] | 221 | ```toml |
| 222 | # Cargo.toml |
| 223 | |
| 224 | [build-dependencies] |
| David Tolnay | 5f3fb89 | 2020-09-01 23:02:57 -0700 | [diff] [blame] | 225 | cxx-build = "0.4" |
| David Tolnay | cc9ece5 | 2020-04-29 18:57:05 -0700 | [diff] [blame] | 226 | ``` |
| 227 | |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 228 | ```rust |
| 229 | // build.rs |
| 230 | |
| 231 | fn main() { |
| David Tolnay | f8ed073 | 2020-04-29 12:34:47 -0700 | [diff] [blame] | 232 | cxx_build::bridge("src/main.rs") // returns a cc::Build |
| David Tolnay | 278f6fc | 2020-09-01 16:16:57 -0700 | [diff] [blame] | 233 | .file("src/demo.cc") |
| Philip Craig | 7e14e2e | 2020-05-09 10:42:30 +0100 | [diff] [blame] | 234 | .flag_if_supported("-std=c++11") |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 235 | .compile("cxxbridge-demo"); |
| 236 | |
| 237 | println!("cargo:rerun-if-changed=src/main.rs"); |
| David Tolnay | 278f6fc | 2020-09-01 16:16:57 -0700 | [diff] [blame] | 238 | println!("cargo:rerun-if-changed=src/demo.cc"); |
| 239 | println!("cargo:rerun-if-changed=include/demo.h"); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 240 | } |
| 241 | ``` |
| 242 | |
| 243 | <br> |
| 244 | |
| 245 | ## Non-Cargo setup |
| 246 | |
| 247 | For use in non-Cargo builds like Bazel or Buck, CXX provides an alternate way of |
| 248 | invoking the C++ code generator as a standalone command line tool. The tool is |
| 249 | packaged as the `cxxbridge-cmd` crate on crates.io or can be built from the |
| 250 | *cmd* directory of this repo. |
| 251 | |
| 252 | ```bash |
| 253 | $ cargo install cxxbridge-cmd |
| 254 | |
| 255 | $ cxxbridge src/main.rs --header > path/to/mybridge.h |
| 256 | $ cxxbridge src/main.rs > path/to/mybridge.cc |
| 257 | ``` |
| 258 | |
| 259 | <br> |
| 260 | |
| 261 | ## Safety |
| 262 | |
| 263 | Be aware that the design of this library is intentionally restrictive and |
| 264 | opinionated! It isn't a goal to be powerful enough to handle arbitrary |
| 265 | signatures in either language. Instead this project is about carving out a |
| 266 | reasonably expressive set of functionality about which we can make useful safety |
| 267 | guarantees today and maybe extend over time. You may find that it takes some |
| 268 | practice to use CXX bridge effectively as it won't work in all the ways that you |
| 269 | are used to. |
| 270 | |
| 271 | Some of the considerations that go into ensuring safety are: |
| 272 | |
| 273 | - By design, our paired code generators work together to control both sides of |
| 274 | the FFI boundary. Ordinarily in Rust writing your own `extern "C"` blocks is |
| 275 | unsafe because the Rust compiler has no way to know whether the signatures |
| 276 | you've written actually match the signatures implemented in the other |
| 277 | language. With CXX we achieve that visibility and know what's on the other |
| 278 | side. |
| 279 | |
| 280 | - Our static analysis detects and prevents passing types by value that shouldn't |
| 281 | be passed by value from C++ to Rust, for example because they may contain |
| 282 | internal pointers that would be screwed up by Rust's move behavior. |
| 283 | |
| 284 | - To many people's surprise, it is possible to have a struct in Rust and a |
| 285 | struct in C++ with exactly the same layout / fields / alignment / everything, |
| 286 | and still not the same ABI when passed by value. This is a longstanding |
| 287 | bindgen bug that leads to segfaults in absolutely correct-looking code |
| 288 | ([rust-lang/rust-bindgen#778]). CXX knows about this and can insert the |
| 289 | necessary zero-cost workaround transparently where needed, so go ahead and |
| 290 | pass your structs by value without worries. This is made possible by owning |
| 291 | both sides of the boundary rather than just one. |
| 292 | |
| 293 | - Template instantiations: for example in order to expose a UniquePtr\<T\> type |
| 294 | in Rust backed by a real C++ unique\_ptr, we have a way of using a Rust trait |
| 295 | to connect the behavior back to the template instantiations performed by the |
| 296 | other language. |
| 297 | |
| 298 | [rust-lang/rust-bindgen#778]: https://github.com/rust-lang/rust-bindgen/issues/778 |
| 299 | |
| 300 | <br> |
| 301 | |
| 302 | ## Builtin types |
| 303 | |
| David Tolnay | 559fbb3 | 2020-03-17 23:32:20 -0700 | [diff] [blame] | 304 | In addition to all the primitive types (i32 <=> int32_t), the following |
| David Tolnay | 06515f0 | 2020-03-17 23:28:02 -0700 | [diff] [blame] | 305 | common types may be used in the fields of shared structs and the arguments and |
| 306 | returns of functions. |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 307 | |
| 308 | <table> |
| 309 | <tr><th>name in Rust</th><th>name in C++</th><th>restrictions</th></tr> |
| David Tolnay | 750755e | 2020-03-01 13:04:08 -0800 | [diff] [blame] | 310 | <tr><td>String</td><td>rust::String</td><td></td></tr> |
| 311 | <tr><td>&str</td><td>rust::Str</td><td></td></tr> |
| David Tolnay | efe8105 | 2020-04-14 16:28:24 -0700 | [diff] [blame] | 312 | <tr><td>&[u8]</td><td>rust::Slice<uint8_t></td><td><sup><i>arbitrary &[T] not implemented yet</i></sup></td></tr> |
| David Tolnay | 5f3fb89 | 2020-09-01 23:02:57 -0700 | [diff] [blame] | 313 | <tr><td><a href="https://docs.rs/cxx/0.4/cxx/struct.CxxString.html">CxxString</a></td><td>std::string</td><td><sup><i>cannot be passed by value</i></sup></td></tr> |
| David Tolnay | 750755e | 2020-03-01 13:04:08 -0800 | [diff] [blame] | 314 | <tr><td>Box<T></td><td>rust::Box<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> |
| David Tolnay | 5f3fb89 | 2020-09-01 23:02:57 -0700 | [diff] [blame] | 315 | <tr><td><a href="https://docs.rs/cxx/0.4/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> |
| David Tolnay | 347c3d0 | 2020-04-24 16:14:07 -0700 | [diff] [blame] | 316 | <tr><td>Vec<T></td><td>rust::Vec<T></td><td><sup><i>cannot hold opaque C++ type</i></sup></td></tr> |
| David Tolnay | 5f3fb89 | 2020-09-01 23:02:57 -0700 | [diff] [blame] | 317 | <tr><td><a href="https://docs.rs/cxx/0.4/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> |
| David Tolnay | addc748 | 2020-03-29 22:19:44 -0700 | [diff] [blame] | 318 | <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> |
| David Tolnay | 31b5aad | 2020-04-10 19:35:47 -0700 | [diff] [blame] | 319 | <tr><td>Result<T></td><td>throw/catch</td><td><sup><i>allowed as return type only</i></sup></td></tr> |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 320 | </table> |
| 321 | |
| David Tolnay | 736cbca | 2020-03-11 16:49:18 -0700 | [diff] [blame] | 322 | The C++ API of the `rust` namespace is defined by the *include/cxx.h* file in |
| 323 | this repo. You will need to include this header in your C++ code when working |
| 324 | with those types. |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 325 | |
| 326 | The following types are intended to be supported "soon" but are just not |
| 327 | implemented yet. I don't expect any of these to be hard to make work but it's a |
| 328 | matter of designing a nice API for each in its non-native language. |
| 329 | |
| 330 | <table> |
| 331 | <tr><th>name in Rust</th><th>name in C++</th></tr> |
| David Tolnay | 84f232e | 2020-01-08 12:22:56 -0800 | [diff] [blame] | 332 | <tr><td>BTreeMap<K, V></td><td><sup><i>tbd</i></sup></td></tr> |
| 333 | <tr><td>HashMap<K, V></td><td><sup><i>tbd</i></sup></td></tr> |
| David Tolnay | 239d05f | 2020-03-13 01:36:50 -0700 | [diff] [blame] | 334 | <tr><td>Arc<T></td><td><sup><i>tbd</i></sup></td></tr> |
| David Tolnay | 85487b0 | 2020-08-22 06:13:27 -0700 | [diff] [blame] | 335 | <tr><td>Option<T></td><td><sup><i>tbd</i></sup></td></tr> |
| David Tolnay | 84f232e | 2020-01-08 12:22:56 -0800 | [diff] [blame] | 336 | <tr><td><sup><i>tbd</i></sup></td><td>std::map<K, V></td></tr> |
| 337 | <tr><td><sup><i>tbd</i></sup></td><td>std::unordered_map<K, V></td></tr> |
| David Tolnay | 239d05f | 2020-03-13 01:36:50 -0700 | [diff] [blame] | 338 | <tr><td><sup><i>tbd</i></sup></td><td>std::shared_ptr<T></td></tr> |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 339 | </table> |
| 340 | |
| 341 | <br> |
| 342 | |
| 343 | ## Remaining work |
| 344 | |
| 345 | This is still early days for CXX; I am releasing it as a minimum viable product |
| David Tolnay | 3deb2f9 | 2020-04-22 19:16:38 -0700 | [diff] [blame] | 346 | to collect feedback on the direction and invite collaborators. Please check the |
| 347 | open issues. |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 348 | |
| David Tolnay | 9c815df | 2020-09-02 09:54:19 -0700 | [diff] [blame] | 349 | Especially please report issues if you run into trouble building or linking any |
| 350 | of this stuff. I'm sure there are ways to make the build aspects friendlier or |
| 351 | more robust. |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 352 | |
| 353 | Finally, I know more about Rust library design than C++ library design so I |
| 354 | would appreciate help making the C++ APIs in this project more idiomatic where |
| 355 | anyone has suggestions. |
| 356 | |
| 357 | <br> |
| 358 | |
| 359 | #### License |
| 360 | |
| 361 | <sup> |
| 362 | Licensed under either of <a href="LICENSE-APACHE">Apache License, Version |
| 363 | 2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option. |
| 364 | </sup> |
| 365 | |
| 366 | <br> |
| 367 | |
| 368 | <sub> |
| 369 | Unless you explicitly state otherwise, any contribution intentionally submitted |
| 370 | for inclusion in this project by you, as defined in the Apache-2.0 license, |
| 371 | shall be dual licensed as above, without any additional terms or conditions. |
| 372 | </sub> |