Godot 4.3 GDExtension is more strict about wrapping Godot Objects than 4.2

Godot Version

4.3

Question

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:

protected:

static void _bind_methods();

godot::GridContainer GridFlow;
godot::FlowContainer CenterDetailsFlow;
godot::Label	CenterSizeLabel;
godot::OptionButton CenterSizes;
godot::Label	CenterVertexRatioLabel;
godot::OptionButton CenterVertexRatios;
    ...

It seems like Godot 4.3 is going to force me to change these all to pointers and memnew/memdelete them.

Is there any option to allow me to use Godot Objects that I don’t care about binding callbacks in the way 4.2 allowed me to?

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.

memory.h

Object.cpp

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 )

1 Like

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 :laughing: