I am working on a custom GDExtension and recently tried upgrading my code base from 4.2 to 4.3. It seems 4.3 is much more strict about forcing me to wrap Godot Objects than 4.2 was, as it force crashes the application if you don’t:
ERROR: BUG: Godot Object created without binding callbacks. Did you forget to use memnew()?
at: (godot-cpp\src\classes\wrapped.cpp:87)
The thing is, I didn’t forget - it was on purpose. There are plenty of times where it feels more practical to have Godot Objects as class members instead of dynamically creating everything. For example, I have a lot of UI classes that inherit PanelContainer and have many UI controls as class members:
That is not the case, all Godot::objects that are created with new need to use memnew in order to glue with the Godot’s::object class (Node inherits Object class). If Godot engine needs to interact with it it needs the memnew glue.
See memory.h, and the object.cpp for post initialization of memnew.
Thanks, this is clear to me and I do this anywhere where I need to use Signals, etc. But in my example, these Godot Objects are not created with new or memnew, they are implicitly constructed as part of the class. This seemed to be working fine for my needs in Godot 4.2, but 4.3 is explicitly crashing because of it.
I do accept that the answer may be “just because Godot 4.2 let you do this, doesn’t mean you should have been doing this”, I just wanted to be sure before I set out on a significant code refactor…
I would have to investigate the history more, but the functionality did change subtly, but overall looks the same. ( I think this has been a requirement since the beginning of Godot. And if not followed could lead to leaked memory)
I wonder if there was some implicit call to postinitialize the class (which eventually calls bind_methods) when allocating memory.
Even so the impact is small, just change new calls to memnew and that’s it.
Node = new Node(args)
// Changes to
Node = memnew( Node(args) )
And a similar thing is required for memdelete
If you want objects on the stack you could try calling postinitialize_handler manually. ( And predelete_handler respectfully )
Thanks very much for your insights! I am going to proceed with my code refactor with the philosophy of “if it’s a Godot Object, it must be explicitly created and destroyed with memnew and memdelete, regardless of whether I think the engine needs to know about it or not”. Time to make coffee and put on some good music.
I just wanted to try the new FogMode additions and definitely got more than I bargained for here