How to export a tool button with GDExtension?

Godot Version

4.5

Question

I am trying to export a button that calls a function for my custom Godot node. The goal of this button is to recalculate a mesh, when I need it to be recalculated. I am not as concerned about handling that logic yet, my first issue is getting the button to function at all. Here are the .h and .cpp files for what I have tried so far:

voxel_chunk.h

#pragma once

#include <godot_cpp/classes/mesh_instance3d.hpp>

namespace godot { 
    class VoxelChunk : public Node3D{
        GDCLASS(VoxelChunk, Node3D)

        private:
            void _generateWorld();

        protected:
            static void _bind_methods();
        
        public:
            Callable generateWorld();

            VoxelChunk();
            ~VoxelChunk();
    };
}

voxel_chunk.cpp

#include "voxel_chunk.h"
#include <godot_cpp/core/class_db.hpp>

using namespace godot;

VoxelChunk::VoxelChunk() {
}

VoxelChunk::~VoxelChunk()
{
}

void VoxelChunk::_generateWorld()
{
    UtilityFunctions::print("Generated");
}

Callable VoxelChunk::generateWorld(){
    return callable_mp(this, &VoxelChunk::_generateWorld);
}


void VoxelChunk::_bind_methods() {
    ClassDB::bind_method(D_METHOD("generateWorld"), &VoxelChunk::generateWorld);


    ADD_PROPERTY(PropertyInfo(Variant::CALLABLE, "", PROPERTY_HINT_TOOL_BUTTON, "Generate Chunk", PROPERTY_USAGE_EDITOR), "", "generateWorld");
}

Everything compiles properly, and the custom node and button show up, however, when I try to click the button, one of two things will happen. Either the editor will crash, or I will get the error: ERROR: Tool button action “” is an invalid callable. The expected output should be that “Generated” gets printed to the console.

I am fairly new to using GDExtension and Godot with C++, so please forgive me if this the answer is obvious.

Turns out I was not registering the class properly.

In my register_types.cpp file. I had the following: GDREGISTER_RUNTIME_CLASS(VoxelChunk);

It needed to be GDREGISTER_CLASS(VoxelChunk);

The former only lets the node run in-game, while the latter acts more like a GDScript with the tool annotation.