[GH-ISSUE #153] Completely AOT compiled. #95

Open
opened 2026-05-05 11:04:22 -06:00 by gitea-mirror · 12 comments
Owner

Originally created by @pauldotknopf on GitHub (Jul 18, 2019).
Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/153

We need to support end users running a cli tool to generate c++ classes (QObject) and .NET code for interop.

This would remove the need for dynamically invoking methods/properties, in favor or registering raw QObject's with the QML engine. We could also then strictly define what methods/properties are exposed to QML, allowing for reduced memory foot print, as well as increasing the soundness of the app.

Doing this would also remove the need for private headers, which would allow us to run against any 5.X version, instead of the exact version we compiled against. Imagine you create an Ubuntu package, and the underling Qt framework gets a patch update. Your application would be guaranteed to continue to work! Otherwise, your app would have to be recompiled in lock-step.

Originally created by @pauldotknopf on GitHub (Jul 18, 2019). Original GitHub issue: https://github.com/qmlnet/qmlnet/issues/153 We need to support end users running a cli tool to generate c++ classes (QObject) and .NET code for interop. This would remove the need for dynamically invoking methods/properties, in favor or registering raw QObject's with the QML engine. We could also then strictly define what methods/properties are exposed to QML, allowing for reduced memory foot print, as well as increasing the soundness of the app. Doing this would also remove the need for private headers, which would allow us to run against any 5.X version, instead of the exact version we compiled against. Imagine you create an Ubuntu package, and the underling Qt framework gets a patch update. Your application would be guaranteed to continue to work! Otherwise, your app would have to be recompiled in lock-step.
Author
Owner

@pauldotknopf commented on GitHub (Jul 18, 2019):

This would also theoretically improve the performance of the interop between C# and QML, since we wouldn't have to wrap everything with a QVariant, and we wouldn't have to dynamically emit .NET code for interacting with .NET objects.

<!-- gh-comment-id:512659337 --> @pauldotknopf commented on GitHub (Jul 18, 2019): This would also theoretically improve the performance of the interop between C# and QML, since we wouldn't have to wrap everything with a QVariant, and we wouldn't have to dynamically emit .NET code for interacting with .NET objects.
Author
Owner

@shartte commented on GitHub (Apr 13, 2020):

I haven't actually looked at the details of this yet, but would the plans for C# function pointers in .NET 5 help with this? Supposedly those should allow the .NET AOT compilation to work even when function pointers back to "managed land" are being passed via P/Invoke, since those function pointers would not need to be generated at runtime for delegates.

Here's the proposal: https://github.com/dotnet/csharplang/blob/master/proposals/function-pointers.md

<!-- gh-comment-id:613035442 --> @shartte commented on GitHub (Apr 13, 2020): I haven't actually looked at the details of this yet, but would the plans for C# function pointers in .NET 5 help with this? Supposedly those should allow the .NET AOT compilation to work even when function pointers back to "managed land" are being passed via P/Invoke, since those function pointers would not need to be generated at runtime for delegates. Here's the proposal: https://github.com/dotnet/csharplang/blob/master/proposals/function-pointers.md
Author
Owner

@pauldotknopf commented on GitHub (Apr 15, 2020):

This is AOT, but in the opposite direction. Basically, instead of dynamic QObject instances that dynamic methods/properties, we will generate C++ for typed QObject derivatives that can be instantiated in QML, with intellisense, etc.

<!-- gh-comment-id:613788210 --> @pauldotknopf commented on GitHub (Apr 15, 2020): This is AOT, but in the opposite direction. Basically, instead of dynamic ```QObject``` instances that dynamic methods/properties, we will generate C++ for typed ```QObject``` derivatives that can be instantiated in QML, with intellisense, etc.
Author
Owner

@shartte commented on GitHub (Apr 15, 2020):

Ah, essentially "AOT" generated Proxies for QML files / QObject types?
This will be hard for QML files though, since the type of properties and such is dynamic, and one cannot use offline-inspection of a native DLL to get the meta object, essentially.

Especially the "typed" part on the C++ side to improve performance over going through the meta-object-system could lead down a rabbit hole... I.e. would you still only support Q_INVOKABLE/Q_SLOT or allow any C++ method to be called?

p.s.: What are your thoughts on preserving object identity of the managed proxy object? Theoretically, one could store a GCHandle within a dynamic QObject property and reuse it whenever a proxy for the native object is requested from the managed side.

<!-- gh-comment-id:613982839 --> @shartte commented on GitHub (Apr 15, 2020): Ah, essentially "AOT" generated Proxies for QML files / QObject types? This will be hard for QML files though, since the type of properties and such is dynamic, and one cannot use offline-inspection of a native DLL to get the meta object, essentially. Especially the "typed" part on the C++ side to improve performance over going through the meta-object-system could lead down a rabbit hole... I.e. would you still only support Q_INVOKABLE/Q_SLOT or allow any C++ method to be called? p.s.: What are your thoughts on preserving object identity of the managed proxy object? Theoretically, one could store a GCHandle within a dynamic QObject property and reuse it whenever a proxy for the native object is requested from the managed side.
Author
Owner

@pauldotknopf commented on GitHub (Apr 15, 2020):

I'm not sure what you mean by "QML files". I'm only referring to generating the QObject equivalents for each .NET object you wish to generate AOT. Some .NET types could still be left as dynamic, some statically compiled.

Another drive here is that creating a dynamic QObject requires the use of Qt's private headers, which means that when the native shim for Qml.Net is compiled, it only works for that exact version of Qt you compiled for (less portable). This would prevent us from pushing the native lib as a .deb/.rpm package for each distro, since any patch to the system-installed Qt runtime could break your app.

<!-- gh-comment-id:614015431 --> @pauldotknopf commented on GitHub (Apr 15, 2020): I'm not sure what you mean by "QML files". I'm only referring to generating the QObject equivalents for each .NET object you wish to generate AOT. Some .NET types could still be left as dynamic, some statically compiled. Another drive here is that creating a dynamic QObject requires the use of Qt's private headers, which means that when the native shim for Qml.Net is compiled, it only works for that exact version of Qt you compiled for (less portable). This would prevent us from pushing the native lib as a .deb/.rpm package for each distro, since any patch to the system-installed Qt runtime could break your app.
Author
Owner

@shartte commented on GitHub (Apr 15, 2020):

Oooooooooh, my apologies. You mean the C++->.NET direction. QObject proxies for classes defined in .NET, right?
I was talking about the other direction. I'd like the native C++ class hierarchy to be reflected on the .NET side (having typed .NET proxies for QQuickItem and the variants thereof that are dynamically created from QML files, essentially).

<!-- gh-comment-id:614021949 --> @shartte commented on GitHub (Apr 15, 2020): Oooooooooh, my apologies. You mean the C++->.NET direction. QObject proxies for classes defined in .NET, right? I was talking about the other direction. I'd like the native C++ class hierarchy to be reflected on the .NET side (having **typed** .NET proxies for QQuickItem and the variants thereof that are dynamically created from QML files, essentially).
Author
Owner

@pauldotknopf commented on GitHub (Apr 15, 2020):

I'm with you there.

I had a grand idea of creating a DSL that allows you to define objects/methods/properties/inheritance that can be used to generate shim native code and C# code to make it super easy to use C++ in .NET. It would have helped with the interop layer in Qml.Net, and with what you are suggesting. That is a lot of work though :)

MonoCpp came close to achieving this, but IMO, came up short.

<!-- gh-comment-id:614056056 --> @pauldotknopf commented on GitHub (Apr 15, 2020): I'm with you there. I had a grand idea of creating a DSL that allows you to define objects/methods/properties/inheritance that can be used to generate shim native code and C# code to make it super easy to use C++ in .NET. It would have helped with the interop layer in Qml.Net, and with what you are suggesting. That is a lot of work though :) MonoCpp came close to achieving this, but IMO, came up short.
Author
Owner

@shartte commented on GitHub (Apr 16, 2020):

@pauldotknopf Is there already an issue for having typed proxies for QML components?

<!-- gh-comment-id:614457835 --> @shartte commented on GitHub (Apr 16, 2020): @pauldotknopf Is there already an issue for having typed proxies for QML components?
Author
Owner

@pauldotknopf commented on GitHub (Apr 16, 2020):

Checkout INetQObject and INetJsValue types.

<!-- gh-comment-id:614461487 --> @pauldotknopf commented on GitHub (Apr 16, 2020): Checkout ```INetQObject``` and ```INetJsValue``` types.
Author
Owner

@shartte commented on GitHub (Apr 16, 2020):

@pauldotknopf Yeah, but I mean having a generated C# interface for each QML file in the project to allow intellisense, type and error checking.

<!-- gh-comment-id:614482043 --> @shartte commented on GitHub (Apr 16, 2020): @pauldotknopf Yeah, but I mean having a generated C# interface for each QML file in the project to allow intellisense, type and error checking.
Author
Owner

@pauldotknopf commented on GitHub (Apr 17, 2020):

Ah. Maybe some tool to generate C# to interact with a INetQObject? That sounds useful, especially when working with a large number of objects.

<!-- gh-comment-id:615049075 --> @pauldotknopf commented on GitHub (Apr 17, 2020): Ah. Maybe some tool to generate C# to interact with a ```INetQObject```? That sounds useful, especially when working with a large number of objects.
Author
Owner

@shartte commented on GitHub (Apr 17, 2020):

@pauldotknopf Yup, exactly that. Imagine as part of the build process some tool pre-generating a bunch of classes (or interfaces) that correspond 1:1 to your app's QML files, their properties and their inheritance hierarchy. I am prototyping something like that, which would work similar to qmlplugindump, but work on qml files instead.

I am just a sucker for intellisense ;-)

<!-- gh-comment-id:615307590 --> @shartte commented on GitHub (Apr 17, 2020): @pauldotknopf Yup, exactly that. Imagine as part of the build process some tool pre-generating a bunch of classes (or interfaces) that correspond 1:1 to your app's QML files, their properties and their inheritance hierarchy. I am prototyping something like that, which would work similar to qmlplugindump, but work on qml files instead. I am just a sucker for intellisense ;-)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/qmlnet#95
No description provided.