cxx-qt icon indicating copy to clipboard operation
cxx-qt copied to clipboard

Shareing basic types with other rust-qt crates

Open Ayush1325 opened this issue 2 years ago • 8 comments

Currently, Rust-Qt crates like cxx-qt and qmetaobject use different crates for the base types like QString, QColor etc.

In the case of qmetaobject, qttypes contains the definition of the basic types.

I was wondering, if there is any way to have a common crate that wraps the basic types, like QString, QColor, etc.

I am currently working on KConfig bindings for Rust and depend on qttypes. Since I do not depend on qmetaobject itself, it would be pretty useful if the basic types were shared between the two crates.

Also, the goals of both projects seem to be pretty different, qmetaobject is focused on creating QML applications without C++/cmake while cxx-qt seems to be focused on integrating Rust into a Qt application, so they aren't really conflicting in that regard.

With all that said, the way both of these crates are written is somewhat different so I am not completely sure if this is possible.

Ayush1325 avatar Mar 11 '22 18:03 Ayush1325

So for trivial types we simply use Rust structs that have the same representation as the C++ side and we then pass them across the CXX bridge. For opaque types (QColor, QDateTime, QString, QUrl, QVariant) we have to either take a reference to them or pass a cxx::UniquePtr<T> of them.

Once this change #105 lands it should allow for our types from cxx-qt-lib to be used across any CXX bridge definition for other projects quite simply. (just add cxx-qt-lib as a depends, add the generated header and source files to your C++ build command, and add the right include paths etc).

So basically, yes cxx-qt-lib could become a common crate assuming that dependants use CXX for the bridge definition. CXX can use external bindings but I'm not sure how simple or desirable it'd be to use the existing qttypes and integrate that into our build system as it uses the cpp crate and tends to have unsafe code etc - this would require further investigation.

ahayzen-kdab avatar Mar 14 '22 10:03 ahayzen-kdab

Well, qttypes uses the rust-cpp crate which uses cxx crate internally. Basically, it allows writing the CXX bridge code inline instead of having to write a separate cpp file, so it is not all that much different than cxx.

As for the unsafe part, the ffi is the unsafe part, and it is unsafe in cxx as well, so not much difference there.

One major difference with the opaque types handling in qttypes is that not all opaque types have to be wrapped inside a unique_ptr. This is because as long as the classes can be moved around in Rust side freely, (aka classes are Trivially Copyable), the object is simple owned by Rust instead of C++. A lot of base Qt types are actually Trivially Copyable, so it works out pretty well.

The classes that are not Trivially Copyable are pretty much handled by having a wrapper class in C++ which has a unique_ptr to the object.

From what I understand, cxx does allow more type checks than using rust-cpp, but I have not used cxx much so cannot comment on how useful those are.

Ayush1325 avatar Mar 14 '22 11:03 Ayush1325

Right, we also wrap the opaque types and hold a unique_ptr internally as it's passed around. Definitely something to look at later if we can share anything.

ahayzen-kdab avatar Mar 14 '22 11:03 ahayzen-kdab

the rust-cpp crate which uses cxx crate internally

I just checked the Cargo.toml's of all the crates in the rust-cpp repos and do not see cxx used as a dependency. Maybe you're confusing the cxx and cc crates?

Be-ing avatar Mar 14 '22 18:03 Be-ing

the rust-cpp crate which uses cxx crate internally

I just checked the Cargo.toml's of all the crates in the rust-cpp repos and do not see cxx used as a dependency. Maybe you're confusing the cxx and cc crates?

My bad, rust-cpp and cxx crates can be used together. but they do not seem to be dependent on each other.

Ayush1325 avatar Mar 14 '22 18:03 Ayush1325

Also, the goals of both projects seem to be pretty different, qmetaobject is focused on creating QML applications without C++/cmake while cxx-qt seems to be focused on integrating Rust into a Qt application, so they aren't really conflicting in that regard.

Currently, yes, this crate is focused on using Rust in C++ applications and the build is driven by CMake. cxx can do bindings bidirectionally, both C++-to-Rust and Rust-to-C++. I would love to see this crate grow to be usable for creating Qt applications in Rust with the build driven by Cargo (without CMake).

From what I understand, cxx does allow more type checks than using rust-cpp, but I have not used cxx much so cannot comment on how useful those are.

Yes, cxx takes a much more structured approach to C++-Rust interoperation. I suggest to read the cxx documentation if you haven't already, particularly the first 4 chapters.

For context, take a look at the release histories of cxx and qmetaobject. cxx came after qmetaobject. While I appreciate qmetaobject and qttypes, I personally think using cxx is a better way forward in the long term than the unsafe cpp approach of embedding arbitrary C++ code within Rust.

Be-ing avatar Mar 14 '22 19:03 Be-ing

I would love to see this crate grow to be usable for creating Qt applications in Rust with the build driven by Cargo (without CMake).

On that note: #113

Be-ing avatar Mar 14 '22 20:03 Be-ing

While I appreciate qmetaobject and qttypes, I personally think using cxx is a better way forward in the long term than the unsafe cpp approach of embedding arbitrary C++ code within Rust.

I, for one, prefer embedding the C++ code in Rust because it limits the boilerplate for small functions by a lot. This is not arbitrary code being embedded, there is some checking hapenning. While there could be more checking, the cpp! macro is fairly safe. even with the cxx crate you still have to put the arbitrary C++ code somewhere. And i'd argue that having it located where it is used rather that in some other file improves things.

ogoffart avatar Mar 15 '22 17:03 ogoffart