[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)