GDExtension not working with custom STL container

Godot Version

v4.2.2.stable.mono.official [15073afe3]

Question

I have a grid<T, measure_t, Alloc> class for a heap allocation-based STL container. Here is the GitHub repository of this class, there’s also a matrix.h in the repo, but they are independent of each other.

The problem is that if I call the get() method in the code, the compilation will be done successfully, but Godot will shut down after the boot splash, indicating that something has gone wrong.

I’m using MODULE_INITIALIZATION_LEVEL_SCENE for the init level, which will be loaded in the scene edit. However, if I use the MODULE_INITIALIZATION_LEVEL_SERVERS level, which delays the initialization, Godot puts out a warning notification with the following message:

  • This node was saved as class type ‘MapCpp’, which was no longer available when this scene was loaded.

  • Data from the original node is kept as a placeholder until this type of node is available again. It can hence be safely re-saved without risk of data loss.

The warning looks like this, and opening the warning gives out the above messages.

Snipaste_2024-07-31_22-10-47

At the same time, the console gives out:

Any kind of get() call? Are you trying to directly expose the get() function through bind_method?

If you are storing Godot containers inside the grid that could be problematic.

The grid class is a pure STL container, independent of Godot. Initially, I suspected that the allocation was causing the issue. For this reason, I upgraded it to a semi-allocator-aware container and passed in an encapsulation of the DefaultAllocator with an allocator API. However, the error persisted. I also attempted to new something like int, but this didn’t trigger the error, it somehow proves that the allocation is not the cause.

The MapCpp class which contains the grid as a member, inherits Node. Everything works fine as long as I don’t call grid.get(). However, if I do call this method once, the compilation is successful but Godot shuts down after the boot splash. Launching Godot with the console doesn’t receive error messages.

This is what I have in the MapCpp class declaration

// Some usings to shorten declarations
using size_t = int32_t;
using usize_t = uint32_t;
using grid_t = arr2d::grid<CellCpp, usize_t, STLAllocator<CellCpp>>;
grid_t map_grid;

The CellCpp is a simple struct with two float members and a method to construct a Color with its members. It doesn’t produce any problems in its construction, methods, or allocation.

As I said, if I do call the grid.get() once in _ready() or _process(), it’ll blast off everything, although it works fine outside of Godot.

Oh sorry, let me explain this. The grid::get(size_type x, size_type y) is an alternative of multidimensional subscript operator in C++17, for accessing elements of the container. Please don’t confused with godot::Object::get().