-
-
Notifications
You must be signed in to change notification settings - Fork 573
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GDExtension] Casting fails when virtual functions are added #610
Comments
I strongly suspect this issue is fixed by #1050 Before that PR was merged, you could easily end up in a situation were the actual wrapper was a parent class, and godot-cpp happily (and unsafely) cast it to a child class, which would have had the wrong |
@BastiaanOlij: ping! was this fixed with #1050 as mentioned above? |
@MJacred should have been, it's a long long time ago since we had someone report issues around this. |
Let's close for now. We can always reopen :-) |
Further investigating why Ref<> isn't working properly I found a weird issue with casting. In C++ when inheriting it is possible that data structures shift and there is thus no guarantee that the pointer is the same. So:
Could result in the
base_class
pointer not being equal to thesub_class
pointer.The compiler deals with this nicely, so doing the following on our wrapper classes in GDExtensions:
We can see this casts nicely:
But also notice that from XRInterface our pointer is shifted 8 bytes, something is added to the XRInterfaceExtension data which the compiler puts in front of instead of after the data from the super class.
So for now not a problem, until we use Godots own casting logic:
Now our output is:
We see that our original pointer is used but because this is incorrect for our
RefCounted
class we're reading the wrong memory for owner causing a crash if we attempt to use this object.The reason for this is that our
Object::cast_to<T>
uses the owner to ask Godot to perform the cast, and then lookup the wrapper pointer belonging to that owner, which is still our subclass' pointer.This approach to casting thus only works if there is no shift in the data.
So far my theory is that the shift is caused by the introduction of a vtable for the new virtual functions that were introduced and the pointer to this vtable precedes the subclass struct.
The text was updated successfully, but these errors were encountered: