12 ms·
CXX – safe interop between Rust and C++
- bee_rider 5y agoIt seems unfortunate that they decided to stylize this as CXX (all caps). CXX is already in use nearby as the conventional stand-in for the c++ compiler in (for example) makefiles, and the library itself seems to be called cxx (lower case) in their example code.
- LordDragonfang 5y agoShould have been CO2 (An oxidized C)
- bee_rider 5y agoDang it, where were you when they named this thing, that's perfect.
- netr0ute 5y agoWhat's the point of using C++ in Rust when you could use Rust instead and not have to add a cargo package?
- sgeisenh 5y agoThere is a lot of code written in C++. For a lot of large companies, one of the impediments to migrating from C++ to Rust is the investment required to expose the existing C++ interfaces in Rust. There are also many open source libraries written in C++ that you can more easily call from Rust using this bridge library.
- tux3 5y agoIt's not just about using C++ libraries from Rust, but also the other way around. You have 15 million lines of C++ code, and you want to start writing some components in Rust. At the interface, you need a bridge.
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- deadcore 5y agoIf you have existing resources written in C++, external libs, maybe you've created a 'plugin' which is loaded by an application but the plugin is written in Rust and the app is written in C++ and it needs to invoke back into the main applications code. Just examples of stuff where I've had to interop Rust with other things outside of my control :)
- ben-schaaf 5y agoThere's lots of useful C++ libraries that don't have (good) rust bindings.
- onceiwasthere 5y agoI guess if you already have C++ that you'd prefer not to re-write. Also things like graphics programming, while making great strides in rust, are definitely still superior in C++ in certain aspects so you might want to write, say, an OpenGL interface in C++.
- pjmlp 5y agoPlenty of ecosystems where C++ rules and no one is going to rewrite any of those libraries.
- mcronce 5y agoIt takes a lot less time than rewriting [component] in Rust
- detaro 5y agoRewriting a few million lines of existing C++ is not cheap nor quickly done.
- codetrotter 5y agoI have a pretty cool use case where I successfully interfaced between C++ and Rust code. This was for a project consisting of a sculpture with a bunch of LED strips on it, and my part was to do the programming, electronics and wiring for it. To control the LED strips I use Teensy 3.2 microcontroller boards, with the OctoWS2811 adaptor board [0], along with an industrial singleboard computer. The Teensy 3.2 boards I programmed using the Arduino libraries and the OctoWS2811 library [1]. The code I wrote for this part was C++. (But I don’t use the Arduino IDE, I use JetBrains CLion.) Compiling and flashing the firmware for the Teensy, and disconnecting and reconnecting cables etc was making the development a bit annoying. So in Rust I wrote a LED simulator program that renders the “pixels” of the LED strips on my screen, and I compiled my C++ code that I’ve written for the microcontrollers on the host, with some shims that I wrote to provide some functions that my firmware uses, and I link this with my Rust program. The end result is that I have a fully functioning LED simulator that I use while developing, that runs on my computer. It runs on both macOS and Linux. And then the same C++ code of mine gets included and built without modification when I build my firmware for the microcontrollers. It is work that I am very satisfied about :) Should also note that I use the bindgen crate, not cxx. https://crates.io/crates/bindgen https://crates.io/crates/bindgen [0]: https://www.pjrc.com/store/octo28_adaptor.html https://www.pjrc.com/store/octo28_adaptor.html [1]: https://www.pjrc.com/teensy/td_libs_OctoWS2811.html https://www.pjrc.com/teensy/td_libs_OctoWS2811.html
- chris_overseas 5y agoThis sounds great, I'd been thinking about creating something similar (I also have a project with Teensy 3.2/4.0, OctoWS2811 and CLion). Is there any chance you'd be willing to open source it? In particular I'd be interested in what you did to get the Teensy code compiling and running on the host with the shims you mention.
- girvo 5y agoIf your board supports it, the Zephyr RTOS and build tools support building your firmware for a Linux binary target too :) even has a neat RPC protocol to test the firmware on your computer rather than on the board. Probably too much for a Teensy tho, but it is supported: https://docs.zephyrproject.org/latest/boards/arm/teensy4/doc/index.html https://docs.zephyrproject.org/latest/boards/arm/teensy4/doc...
- misja111 5y agoI would have liked 'CRust' better
- zabzonk 5y agoI agree - .cxx is one of the extensions used to differentiate C and C++ code (not that I would recommend its use) and having the library called this may lead to confusion.
- oaiey 5y agoAlso there is C++/CX (which is C++ interop with the WinRT runtime on Windows).
- ansible 5y agoIt was taken quite a while ago: https://crates.io/crates/crust https://crates.io/crates/crust Seems to be an actually useful P2P networking library, not name squatted.
- steeve 5y agoI'm using it and it's really well thought out. Worth noting also is autocxx [1], which is like bindgen, but generates cxx directives. Very clever too. It even allows owning C++ types on the stack. 1. https://github.com/google/autocxx https://github.com/google/autocxx
- VWWHFSfQ 5y agoOooh autocxx looks very nice. Thanks for sharing that!
- rvz 5y agoI'm not sure how this can scale since it is still not automatic and requires tweaking and maintenance of the bindings; or even if the library has a new update. (As there can be new errors, bugs generated from those bindings) It still would be painful to maintain and update your Rust project and cargo configs with your C++ code alongside a third party crate maintained by one person in the project. D Lang is probably the only language that has this built into into the language and is done automatically. I'd still rather go for a first party library with this support or C++ interop support feature built into the language like D with the whole requirement of it being completely automatic.
- aaron_m04 5y agoI was under the impression that both .cpp and .cc were far more common.
- gavinray 5y agoSurprisingly, Swift can do C++ direct interop too, without writing any mappings/type definitions: https://forums.swift.org/t/swift-and-c-interoperability-workgroup-announcement/54998 https://forums.swift.org/t/swift-and-c-interoperability-work... https://github.com/apple/swift/blob/main/docs/CppInteroperability/CppInteroperabilityManifesto.md https://github.com/apple/swift/blob/main/docs/CppInteroperab... https://github.com/apple/swift/blob/main/docs/CppInteroperability/GettingStartedWithC%2B%2BInterop.md https://github.com/apple/swift/blob/main/docs/CppInteroperab...
- worik 5y ago
- dang 5y agoRelated: CXX-Qt: Safe Rust bindings for Qt - https://news.ycombinator.com/item?id=30525752 https://news.ycombinator.com/item?id=30525752 - March 2022 (108 comments) CXX - Safe interop between Rust and C++ - https://news.ycombinator.com/item?id=26565444 https://news.ycombinator.com/item?id=26565444 - March 2021 (32 comments) CXX – safe interop between Rust and C++ - https://news.ycombinator.com/item?id=25126280 https://news.ycombinator.com/item?id=25126280 - Nov 2020 (1 comment) The CXX Debate - https://news.ycombinator.com/item?id=24245372 https://news.ycombinator.com/item?id=24245372 - Aug 2020 (4 comments)
- didip 5y agoI am curious Dang, do you do this manually or do you have an automated script for digging relevant submissions in the past?
- dang 5y agoIt's sort of hybrid. Here are some past explanations https://news.ycombinator.com/item?id=27726982 https://news.ycombinator.com/item?id=27726982 (July 2021) https://news.ycombinator.com/item?id=27284079 https://news.ycombinator.com/item?id=27284079 (May 2021) https://news.ycombinator.com/item?id=27236708 https://news.ycombinator.com/item?id=27236708 (May 2021) https://news.ycombinator.com/item?id=26886074 https://news.ycombinator.com/item?id=26886074 (April 2021) https://news.ycombinator.com/item?id=26245003 https://news.ycombinator.com/item?id=26245003 (Feb 2021) https://news.ycombinator.com/item?id=26158300 https://news.ycombinator.com/item?id=26158300 (Feb 2021) (I made that list using the same software :))
- kupopuffs 5y agoWhat drives you? What's your ~motivation~?
- dang 5y agoNot sure what motivation you're asking about. If you mean motivation for posting links to past discussions—it's my job to help HN be as interesting as possible (see https://hn.algolia.com/?dateRange=all&page=0&prefix=true&sort=byDate&type=comment&query=curiosity%20optimiz%20by:dang https://hn.algolia.com/?dateRange=all&page=0&prefix=true&sor...), and readers seem to find those links interesting.
- cjg 5y agoGiven that C is a subset of C++ (meh), can you use this to generate safe bindings for C? Most C integration recommendations I've seen suggest using bindgen, but that doesn't give safe bindings.
- maxnoe 5y agoI guess this relies on reference counting via smart pointers
- pcwalton 5y agocxx doesn't rely on reference counting. If you're using reference counted smart pointers in C++, then cxx can bind to them. But it won't impose the overhead of reference counting if you aren't already using it.
- pornel 5y agoNot really. The library internally already uses a C ABI, because that's what both C++ and Rust can agree on, but that ABI is not for consumption from C. The point of this library is to preserve higher-level Rust/C++ features like destructors, generic containers, smart pointers, and other things that C can't express.
- cjg 5y agoI meant generating a safe Rust API for existing C code rather than calling an existing Rust API from C.
- pornel 5y agoIn that direction it's difficult, because C source code doesn't contain machine-readable information about ownership (who and when can free a pointer), lifetimes, or thread safety. C annotations for aliasing, nullability, and lenghts of arrays (malloced, not VLA) are very basic, and rarely used. Lots of C code isn't even const-correct. Some of these properties could be deduced by a Sufficiently Smart Compiler, but you'd probably need an A.I. that reads the docs.
- ognarb 5y agoI used this on a personal projectto use the Lyon library to draw custom shapes in a qml app. If someone is interested I wrote a blog post about it: https://carlschwan.eu/2021/01/20/efficient-custom-shapes-in-qtquick-with-rust/ https://carlschwan.eu/2021/01/20/efficient-custom-shapes-in-...
- KptMarchewa 5y agoIMO PyO3 project is more useful. C++ and Rust cover similar field, while Python and Rust are good at so vastly different things that they complement each other much more.
- pcwalton 5y agoBoth cxx and pyo3 are useful, and there's no need for them to compete. cxx is used in production at massive scale.
- kmeisthax 5y agoThe purpose of C++/Rust bridging is to allow adding Rust code to existing C++ projects. PyO3 lets you embed a Python interpreter in an otherwise Rust-only application. They serve two different markets - though, if you really needed to, you could embed both C++ libraries and CPython in the same Rust app.
- sevbo 5y ago
- talal7860 5y ago
- WalterBright 5y agoD does this as: extern (C++) int foo(long x); and takes care of the C++ name mangling and function call ABI for your. It works for structs, inheritance, COM classes, member functions, namespaces, typedefs, even templates.
- lifthrasiir 5y agoFor the reference Rust did consider a similar style of C++ FFI back then [1] [2] [3], but to my knowledge it went nowhere due to the sheer amount of work required and the inability to future-proof. Inline assembly is another similar feature that D is substantially different from Rust, and the rationale for Rust [4] was also similar: D's inline assembly DSL only works in x86 and x86-64. [1] https://github.com/rust-lang/rust/issues/5853 https://github.com/rust-lang/rust/issues/5853 [2] https://github.com/rust-lang/rfcs/issues/602 https://github.com/rust-lang/rfcs/issues/602 [3] https://internals.rust-lang.org/t/better-c-interoperability/2650 https://internals.rust-lang.org/t/better-c-interoperability/... [4] https://rust-lang.github.io/rfcs/2873-inline-asm.html#implement-an-embedded-dsl https://rust-lang.github.io/rfcs/2873-inline-asm.html#implem...
- nicwilson 5y ago> D's inline assembly DSL only works in x86 and x86-64. You're conflating DMD (the reference compiler) with the language here. LDC and GDC (the LLVM and GCC based D compilers) both support GCC style "extended" inline assembly[0] and LDC even allows you to write inline LLVM IR. [0]: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
- WalterBright 5y agoYou're quite right, the D language leaves the inline assembler as implementation defined. DMD has a quite nice assembler that was lifted and updated from the older Digital Mars C++ inline assembler. Each of the D compilers supports inline assembler for each of the targets the particular compiler supports.
- 5y ago
- rajman187 5y agoI used this as an intermediate step for getting a small rust geospatial library working with Google S2 Sphere, which is written in C++, until the Rust implementation is ready. It works flawlessly. David Tolnay (https://github.com/dtolnay https://github.com/dtolnay) is great
- saghm 5y agoIn case others are curious, dtolnay has written a huge number of proc macros that are widely used in the Rust ecosystem; in addition to cxx, he's the author of `serde` (library that supports serialization/deserialization in Rust), `thiserror` and `anyhow` (two of the most commonly used error handling libraries now that the fervor of new error handling libraries has died down), and even several utilities for writing new proc macros like `paste` (a way to concatenate identifiers for generating names of things in macro generation), `watt` (an engine for running proc macros sandboxed in WASM instead of directly in the rust compiler), and `proc-macro2` (an alternate API for creating proc macros that's used almost exclusively instead of directly using the standard library). He's like the Greek god of proc macros. I don't know if he was involved at all in their creation, but he's by far the most prolific proc macro author, and he seems to have an innate understanding of how to use them that goes far beyond what I imagine anyone really considered when they were created. Rust would still be the same language without his work, but it wouldn't feel at all like it, and there's a strong case to be made that Rust would not be anywhere close to as successful as it is today with him.
- paledot 5y agoWhen you mentioned serde, my reaction was, "oh, that's why the name sounds familiar". And then you mentioned anyhow. And proc-macro2. My goodness he's prolific. As someone who has been dragged down to the proc macro layer somewhat against my will, I'm not sure if I should be in awe or terror of an intellect that can be so consistently successful and useful in that world.
- rajman187 5y agoWorth sharing also is the async implementation that works with C++20 coroutines https://github.com/pcwalton/cxx-async https://github.com/pcwalton/cxx-async
- Galanwe 5y agoWhat is so wrong with FFI? I've been using that since decades without anything to complain about. It's simple, to the point, and allows you to have your library used by 99% of existing language, not just rust and c++.
- ben-schaaf 5y agoCXX is effectively a FFI. If you're referring specifically to a C FFI then both C++ and rust already have that, but using CXX automates a lot of the work that would be required to actually use it.