[HN Gopher] CXX - safe interop between Rust and C++ ___________________________________________________________________ CXX - safe interop between Rust and C++ Author : synergy20 Score : 245 points Date : 2022-03-10 14:47 UTC (8 hours ago) (HTM) web link (cxx.rs) (TXT) w3m dump (cxx.rs) | talal7860 wrote: | rvz wrote: | I'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. | gavinray wrote: | Surprisingly, Swift can do C++ direct interop too, without | writing any mappings/type definitions: | | https://forums.swift.org/t/swift-and-c-interoperability-work... | | https://github.com/apple/swift/blob/main/docs/CppInteroperab... | | https://github.com/apple/swift/blob/main/docs/CppInteroperab... | worik wrote: | If you are in the unfortunate position of having to use | swift.... | pcwalton wrote: | autocxx is a companion library that provides what you're | looking for. https://github.com/google/autocxx | dureuill wrote: | That _attempts_ to provide it. I have been trying to use | autocxx for a while, without success at the moment. | | It is very actively developed though so I trust that we'll | get there eventually. | aaron_m04 wrote: | I was under the impression that both .cpp and .cc were far more | common. | cylon13 wrote: | You may have replied to the wrong comment thread | couchand wrote: | FFI is painful, to be sure. Making sure the bindings you say | you're using match the ones you're actually using is tedious | and error-prone. | | Which is where CXX comes in: the static analysis tells you if | you're holding it wrong. So to your first point, the compiler | will tell you exactly what needs to change. | | I don't know what the developer experience with D/C++ interop | looks like, but unless I'm missing something big I'd assume | you'd still need to make changes when the library has updates. | girvo wrote: | It's also built into Nim, for what it's worth, though I do | think D's handling of C++ is more ergonomic. | rajman187 wrote: | I 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) is great | bee_rider wrote: | It 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 wrote: | Should have been CO2 (An oxidized C) | bee_rider wrote: | Dang it, where were you when they named this thing, that's | perfect. | WalterBright wrote: | D 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. | rajman187 wrote: | Worth sharing also is the async implementation that works with | C++20 coroutines https://github.com/pcwalton/cxx-async | KptMarchewa wrote: | IMO 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. | kmeisthax wrote: | The 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. | pcwalton wrote: | Both cxx and pyo3 are useful, and there's no need for them to | compete. cxx is used in production at massive scale. | netr0ute wrote: | What's the point of using C++ in Rust when you could use Rust | instead and not have to add a cargo package? | mcronce wrote: | It takes a lot less time than rewriting [component] in Rust | detaro wrote: | Rewriting a few million lines of existing C++ is not cheap nor | quickly done. | codetrotter wrote: | I 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 | | [0]: https://www.pjrc.com/store/octo28_adaptor.html | | [1]: https://www.pjrc.com/teensy/td_libs_OctoWS2811.html | chris_overseas wrote: | This 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 wrote: | If 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/do | c... | tux3 wrote: | It'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] | [deleted] | deadcore wrote: | If 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 wrote: | There's lots of useful C++ libraries that don't have (good) | rust bindings. | onceiwasthere wrote: | I 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++. | sgeisenh wrote: | There 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. | pjmlp wrote: | Plenty of ecosystems where C++ rules and no one is going to | rewrite any of those libraries. | sevbo wrote: | dang wrote: | Related: | | _CXX-Qt: Safe Rust bindings for Qt_ - | 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 - March 2021 (32 | comments) | | _CXX - safe interop between Rust and C++_ - | https://news.ycombinator.com/item?id=25126280 - Nov 2020 (1 | comment) | | _The CXX Debate_ - https://news.ycombinator.com/item?id=24245372 | - Aug 2020 (4 comments) | didip wrote: | I am curious Dang, do you do this manually or do you have an | automated script for digging relevant submissions in the past? | dang wrote: | It's sort of hybrid. Here are some past explanations | | https://news.ycombinator.com/item?id=27726982 (July 2021) | | https://news.ycombinator.com/item?id=27284079 (May 2021) | | https://news.ycombinator.com/item?id=27236708 (May 2021) | | https://news.ycombinator.com/item?id=26886074 (April 2021) | | https://news.ycombinator.com/item?id=26245003 (Feb 2021) | | https://news.ycombinator.com/item?id=26158300 (Feb 2021) | | (I made that list using the same software :)) | kupopuffs wrote: | What drives you? What's your ~motivation~? | dang wrote: | Not 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&sor...) | , and readers seem to find those links interesting. | tus666 wrote: | That is so meta. | misja111 wrote: | I would have liked 'CRust' better | zabzonk wrote: | I 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 wrote: | Also there is C++/CX (which is C++ interop with the WinRT | runtime on Windows). | ansible wrote: | It was taken quite a while ago: | | https://crates.io/crates/crust | | Seems to be an actually useful P2P networking library, not name | squatted. | ognarb wrote: | I 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-... | cjg wrote: | Given 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 wrote: | I guess this relies on reference counting via smart pointers | pcwalton wrote: | cxx 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 wrote: | Not 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 wrote: | I meant generating a safe Rust API for existing C code rather | than calling an existing Rust API from C. | dangerbird2 wrote: | bindgen[1] already exists to autogenerate a rust API from c | headers. It's inherently unsafe because C code is | inherently unsafe. In particular, there is no language | constructs like destructors or constructors, so you can't | naively create a C-based API that can prevent | memory/resource leaks and use after free errors. While C++ | does have the same issues as C with unsafe pointer | semantics, it does have constructors, destructors, and | other features that map almost perfectly with Rust's RAII- | based resource management, making it pretty easy to | generate a safe(ish) rust interface. In practice, it's | pretty easy to create a safe rust API from a C library: use | bindgen to create the low-level unsafe API, then create | rust wrappers using the ad-hoc creation and descruction | library functions to implement RAII. | | [1] https://rust-lang.github.io/rust-bindgen/ | pornel wrote: | In 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. | girvo wrote: | I'm imagining an interactive tool where it asks those | questions of the developer when generating the binding | code (c2nim is what I use regularly) | woodruffw wrote: | If we're being pedantic (and pedantry matters for safety!) C | hasn't been a subset of C++ for a while: they have different | type aliasing rules (well-defined aliases in C can be UB in | C++), different direct initialization syntaxes, flexible array | members, etc. | kmeisthax wrote: | Probably not, and the reason why bindgen code is marked | `unsafe` is because that's the default for _all_ Rust FFI. You | can 't automatically examine a set of C function signatures and | conclude whether or not they're safe - so it's sound to just | treat them all as `unsafe` and have the developer document what | their safety requirements are, or provide wrapper functions | that enforce safety checks at runtime. | bluejekyll wrote: | The problem is that it's not easy to give safe bindings into C | because C's memory model is all unsafe by Rusts definitions. | You have to manually inspect the C usage of pointers and such | to create the semantics in Rust that make its usage safe. | steeve wrote: | I'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 | VWWHFSfQ wrote: | Oooh autocxx looks very nice. Thanks for sharing that! ___________________________________________________________________ (page generated 2022-03-10 23:00 UTC)