gir.core
gir.core copied to clipboard
Do not use reflection to create objects from IntPtr but SafeHandles
Currently we use reflection to create an object from an IntPtr:
https://github.com/gircore/gir.core/blob/cc0732290999a390478602c51bafaf3650d8d006/Libs/GObject-2.0/Native/Classes/ObjectWrapper.cs#L70
https://github.com/gircore/gir.core/blob/2e2575061fca2cbdc7f359195e59ec7411ed998b/Libs/GObject-2.0/Native/Classes/BoxedWrapper.cs#L59
This is necessary because the TypeDictioanry only returns our instance type for a given GType.
If we update the Native Methods in a way that they return a concrete SafeHandle instead of an IntPtr and each SafeHandle provides a method like CreateInstance
this method could create the concrete instance and effectively wrap itself into an object.
Currently only records use SafeHandle. For this to work classes would need to use SafeHandles, too.
One point which is not completely solved with this is that a GValue
holding a boxed type can only return an IntPtr
and not a SafeHandle
~~In this case we can create the concrete SafeHandle (probably via reflection) and again call CreateInstance
~~
Another possibility is that the type dictionary does carry an action which accepts an IntPtr
and creates the needed SafeHandle. In This way if one has the GType
and an IntPtr
one could get the correct action from the type dictioanry and with this the SafeHandle, which itself can create the instance. Thus avoiding reflection alltogether.
There is a special cases for GDK Event. In this case the given type does not correlate to one class, but to many different classes / events. If we can detect this scenario during generation time, we can generate all the needed code in the safe handle.
As this code is currently not generated, we need to allow the CreateInstance
method of the SafeHandle to be customizeable.
This code should get obsolete with it: https://github.com/gircore/gir.core/blob/395bf92f8d646dd7aff71bd79ba3829b089df5e1/src/Generation/Generator3/Generation/Record/PublicClass/PublicClassTemplate.cs#L36
https://github.com/gircore/gir.core/blob/395bf92f8d646dd7aff71bd79ba3829b089df5e1/src/Libs/GObject-2.0/Internal/Classes/BoxedWrapper.cs#L54
https://github.com/gircore/gir.core/blob/395bf92f8d646dd7aff71bd79ba3829b089df5e1/src/Libs/GObject-2.0/Internal/Classes/BoxedWrapper.cs#L44
Hint: Boxed types have a copy/free function pair, which can be implemented via refcounting
Update: It is not possible to rely on a safe handle which knows the C/C# types as the returned safe handle could be of type „Widget“ but the instance be of type „Button“. It is always necessary to detect the „real“ type of an instance.
Using safe handles allows to differentiate between owned and unowned handles. This would simplify the object constructor which currently requires an intptr and the information of the ptr is owned or not as a bool.
Alternatively it is possible with dotnet 7 to define a static interface method which creates an instance of an object.
The safehandle on the other hand could carry the information regarding it's GType and dotnet type. Meaning if we have a handle we automatically know it's type in C and dotnet world.