Rust and C++ Interoperability
slint-ui.com
slint-ui.com
Regarding Slint and all the other new GUI toolkits, one thing I don't understand is why they all seem to completely ignore any controls more complicated than the basics (buttons, checkboxes, drop downs, spin controls, sliders, radio buttons, and a basic list control).
A To-Do app is a proof of concept, not an endgame.
Beyond those basics I need combo boxes, date time pickers, color pickers, font pickers (fonts are hard, I get it, but my users expect access to system fonts), dockable windows, splits, tabs, modal dialogs, tooltips, masked text input, auto completion text input, context menus, calendar controls, file and directory pickers.
Some of the new toolkits offer an assortment of these, including Slint but they rarely get all of them but the biggest thing missing from pretty much all of them are sophisticated data grids (both list and tree varieties). They need support for custom cell rendering, custom cell edit controls, and variable row heights. They also need to be fast even with tens of thousands of rows.
Oh, and think about your printing story. You don't print a UI obviously but if I'm rendering diagrams and stuff using your rendering facilities I at least need a way to hook them up to the platform's system without just duplicating all of the drawing to a completely different rendering API to make printing work.
This isn't a dig on Slint. I'm eagerly watching it, along with egui, as I desperately look for a cross platform alternative to all the legacy stuff I'm neck deep in. I just can't consider anything that has no good support for data dense applications.
You can still use the old ones, but they will look old and may not behave like you would expect (hidpi displays, touch screen, etc).
wxWidgets and its bindings to many languages exists if that is what you want.
Writing an uniform interface to GUI widgets on many platforms is very much a non-trivial undertaking, there are plenty of failed attempts over the years.
Not GTK+, it sticks out like a sore thumb. Qt gets much closer, though in both cases you can tell something feels off.
(e.g., click an active tab in a tab control in Qt and you won't see the dotted selection line like you would in Win32. That normally indicates you can switch between tabs on the keyboard.)
That would look out of place on MacOS or Windows. Serenity has a Win 2000 look.
edit: I realized that you want the menu entries to be rendered in the fonts themselves
There is a multi-vendor C++ ABI, honored by clang, GCC, Intel's proprietary compiler, and others. It doesn't solve all problems, but provides interoperability.
There are other problems as well from the "hands off" quality of the standard.
Endemic of how bad the situation is regarding C++ DLL:s is that you can't free memory in a different C++ DLL than where it was allocated. Well, you _can_ but most of the time you shouldn't.
Not really. Windows already has specific ABIs that it follows (in NTDLL, MSVCRT, COM DLLs), etc., and that includes virtual functions and exception tables and unwinding and all that. MSVC follows them fine. There's no reason other compilers shouldn't be able to. They just don't seem to want to.
> There are other problems as well from the "hands off" quality of the standard.
Sure, but none of them imply "it's better to defy the convention by default". You still lessen the friction by following the convention.
> Endemic of how bad the situation is regarding C++ DLL:s is that you can't free memory in a different C++ DLL than where it was allocated. Well, you _can_ but most of the time you shouldn't.
That's an orthogonal problem, it's not like you're somehow making that problem any easier by switching to a different ABI than what you know is already conventional on the platform.
It is really only the UNIX folks refusing to adopt the platform idioms.
w.r.t. patents, the only thing I've heard of having been patented is SEH (by Borland, presumably after seeing GCC wasn't implementing the then-patent-less SEH), and even that I'm not sure about the relevance of. (I saw it in the context of WINE, which has to implement the OS-side of it, not the compiler side.)
It is hard to define ABI in the language standard, since ABI heavily depends on the architecture.
(The ABI specify, for example, the calling conventions and in what register goes what, which depends on what kind of register the CPU has)
Isn't the point of a using a different compiler to let it compile your code in different ways? Having to meet an arbitrary ABI is a limiting restriction you may not want.
[0] - https://learn.microsoft.com/en-us/cpp/porting/binary-compat-...
I would understand if *nix folks at least tried to adapt to the platform and were then forced to diverge due to a lack of convention for some new feature, but that isn't the case at all. The compilers follow *nix rules for even the most basic name mangling. They don't seem to have made any initial attempt at platform C++ ABI compatibility whatsoever; they just carried the *nix way into Windows.
Also I think the debug and release build are still incompatible.
IIRC the aspects of the ABI that "broke" across (say) 2013 and 2015 were generally (if not entirely) for the support of newer features, like thread-safe static initialization. That stuff was only standardized in C++11, which is 4 years, not something I'd call a "long time" (especially considering how long it took everyone to finish implementing C++11).
But even worse than that, it's not like GCC had been compatible with the basics before this. It couldn't even bring itself to mangle "void foo() { }" in a platform-compatible way, and it's not like that took until 2015 for Microsoft to settle on.
Quote from the link I pasted in the grand-parent comment:
> The Microsoft C++ (MSVC) compiler toolsets in Visual Studio 2013 and earlier don't guarantee binary compatibility across major versions. You can't link object files, static libraries, dynamic libraries, and executables built by different versions of these toolsets. The ABIs, object formats, and runtime libraries are incompatible.
What would be the point for the GCC team to even try to be compatible with a changing and non-documented ABI?
It wouldn't buy anything to just support how to mangle basic function, as they couldn't still be called. You either had to be fully compatible, or aren't.
And an ABI can be fairly complicated to implement. For example, in what register do we pass a class passed by value? It can change depending on whether some of its members are float, int or double, or whether it has copy constructor. You get anything wrong and the user suddenly get weird crashes that are going to be extremely hard to debug.
It is how I often provide APIs that need to work across (many) compiler boundaries. It is not standardized or anything, but de facto reliable on Windows.
And with the introduction of WinRT extensions, it got even richers.
Naturally one can try to call COM via C, and there are some COM APIs that offer C versions of them, however the tooling is already bad enough for .NET and C++ devs, doing it from C only for masochits or people that are religiouly against productive tooling.
I wish I could find that blog or whatever it was again.
This book has a Windows game, with DirectX, written in Assembly,
https://www.amazon.com/Programming-Tricks-Trade-Premier-Deve...
[1] Herb Sutter's C++ ABI effort was supposed to solve exactly this, but unfortunately never went anywhere. The proposal document pinpoints the problem very well in my opinion: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n40...
AFAIK MSVC compilers explicitly guarantee ABI compatibility since 2015 https://learn.microsoft.com/en-us/cpp/porting/binary-compat-...
as for other platforms, all compilers adhere to Itanium ABI and didnt introduce breaking changes for many years now. Standard libraries, libc++ has explicit ABI guarantee as well (https://libcxx.llvm.org/DesignDocs/ABIVersioning.html).
Libstdc++ uses symbol versioning and only nasty thing happened to it was problem with std::string CoW decade ago, but even that was done neatly and in compatible manner https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_a...
But the parent comment's point is that, even for those different compilers that do follow that inter-compiler ABI, the standard libraries have different binary layouts from other compilers. Your final two links show that GCC and LLVM standard libraries each have the same binary layout as itself between different versions, but not as the other.
We have not attempted to constrain the interface [of the standard library] at this level, because we do not consider doing so feasible at this time
So it wasn't necessarily out of scope, it was just hard to do.I think the reason they don't consider it feasible, is because the C++ ABI would constrain the implementation significantly and there was too much divergence already.
GUI in Rust is a hot topic, and to me it seems SlintUI may be the best general-purpose so far. The reason is rapid iteration and a flexible/intuitive layout system: Slint lets you write UI in a DSL with live preview and style/layout influenced by HTML and CSS, whereas competitors (egui, druid, iced) require you to write the GUI in Rust (which means you must rebuild and rerun to see changes) and have their own style/layout rules. Other competitors are GTK and Qt, but those have their own flaws and moreover, were designed way before Rust and seem to be less "idiomatic".
One of our intern got the UI working with Slint in a few days and since then we didn't feel a strong need to move away from it. We found a few missing features: it was not possible to tell if a Windows is hidden or not. We ended up sending a few patches.
So far our experience has been pretty good with slint-ui. We are not tested the UI on OSX and Linux yet, only windows. On AWS machines with Windows server, the UI fails to launch sometimes because of some missing GL libraries. Also note the licensing of Slint-UI https://github.com/slint-ui/slint/discussions/379.
The misinformed GPL hatred displayed there is also ridiculous.
Requesting a license change from a project that you are not a primary maintainer is more than a little rude.
However, continuing to request a license change even after the owners have explained why they chose the license is an astonishing level of entitlement.
If you don't like the license, don't use the project. That's the deal--take it or leave it.
It was probably more convoluted than necessary since I also then exposed the Rust lib to Python, so C++ <=> Rust <=> Python , but it was indeed fun to implement it all.
This crate is currently mainly aimed at helping people from the Rust group of the Academy Software Foundation (ASWF) to make wrappers for the visual effects ecosystem of libs.[2]
It is nevertheless very useful for all types of other cases.
[1] https://github.com/vfx-rs/cppmm
[2] The above just means effort is prioritized regarding the blockers these libs present due to the resp. C++ features they use.
Most of these are either built on top of cxx or are similar in spirit. So I did not list all of them. The original presentation was only 30 min and there is only so much you can ask a person to read in a blog post:-)
I did try to make it clear that my list is in no way exhaustive.
Are you the same person? I'm just curious. It's a funny coincidence :)