Exception thrown during _bind_methods call

Godot Version

Godot-4.3.stable

Question

I am following the GDExtension C++ example guide on the docs site, but when running it I am getting an exception thrown when loading the extension and not sure why.

The exception is on the very first line of _bind_methonds() and throws the following error message: Exception: Exception 0x80000003 encountered at address 0x7ffbce231c7e

Is there something wrong in my setup:

-- gdexample.hpp
#pragma once

#include <godot_cpp/classes/sprite2d.hpp>

using namespace godot;

class GDExample : public Sprite2D{
    GDCLASS(GDExample, Sprite2D)
public:
    GDExample();

    void _process(double delta) override;

    double get_amplitude() const;
    void set_amplitude(const double p_amplitude);

    double get_speed() const;
    void set_speed(const double p_speed);

protected:
    static void _bind_methods();

private:
    double time_passed;
    double amplitude;
    double speed;
};

-- gdexample.cpp
#include "gdexample.hpp"
#include <godot_cpp/core/class_db.hpp>

using namespace godot;

GDExample::GDExample() {
    // Initialize any variables here.
    time_passed = 0.0;
    amplitude = 10.0;
    speed = 10.0;
}


void GDExample::_process(double delta) {
    time_passed += speed * delta;

    Vector2 new_position = Vector2(
        amplitude + (amplitude * sin(time_passed * 2.0)),
        amplitude + (amplitude * cos(time_passed * 1.5))
    );

    set_position(new_position);
}

double GDExample::get_amplitude() const {
    return amplitude;
}

void GDExample::set_amplitude(const double p_amplitude) {
    amplitude = p_amplitude;
}

double GDExample::get_speed() const {
    return speed;
}

void GDExample::set_speed(const double p_speed) {
    speed = p_speed;
}

void GDExample::_bind_methods() {
    ClassDB::bind_method(D_METHOD("get_amplitude"), &GDExample::get_amplitude);
    ClassDB::bind_method(D_METHOD("set_amplitude", "p_amplitude"), &GDExample::set_amplitude);

    ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "amplitude"), "set_amplitude", "get_amplitude");

    ClassDB::bind_method(D_METHOD("get_speed"), &GDExample::get_speed);
    ClassDB::bind_method(D_METHOD("set_speed", "p_speed"), &GDExample::set_speed);

    ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_speed", "get_speed");
}
-- register_types.cpp
#include "register_types.hpp"

#include "gdexample.hpp"

#include <gdextension_interface.h>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>

using namespace godot;

// TODO: Rename 'example' to extension name
void initialize_example_module(ModuleInitializationLevel p_level) {
	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
		return;
	}

	GDREGISTER_CLASS(GDExample);
}

// TODO: Rename 'example' to extension name
void terminate_example_module(ModuleInitializationLevel p_level) {
	if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) {
		return;
	}
}

extern "C" {
	// Initialization.
	GDExtensionBool GDE_EXPORT GDExtensionInit(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) {
		godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);

		// TODO: Replace function names with updated function names
		init_obj.register_initializer(initialize_example_module);
		init_obj.register_terminator(terminate_example_module);

		init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);

		return init_obj.init();
	}
}

This is a guess, but I wonder if this is the issue. I see that you have followed the example except here.

Since these functions are wrapped in a binder I wonder if the bound functions can’t have attributes attached.

1 Like

I actually added the [[nodiscard]] attributes after I ran into this issue in a failed attempt to see if it would fix it. And my IDE was complaining at me about it not being [[nodiscard]].

I’ve removed it from the original post

1 Like

Because you say IDE, do you still use scons to build?

1 Like

I do not. I am using CMake since it works better with my IDE (Clion). For some additional context:

1 Like

Okay, well you will have to do everything that scons does for build commands.

Obviously the binding mechanism isn’t being built correctly. Unfortunately I don’t know a lot about Godot’s binding implementation. (I will peak at it)

What is the exact exception thrown?

The only thing in the console, or show by my IDE is: Exception: Exception 0xc0000409 encountered at address 0x7ffbd36211d5

No error messages or anything like that. If you think it would be helpful I can clean up the project a bit and push it to GitHub. But by your own submission if there’s nothing syntactical wrong with the project or how it’s built then maybe not that useful

1 Like

Sure, I mean superficially the code all looks good. But just a vague error like that and the fact your are running your own build script makes me suspect it’s a build issue.

I guess doing a search on the vague error I get mentions of an unhandled thrown exception. But I’m not aware that Godot uses any try/catch/throw behavior off the top of my head.

Maybe looking to see if that address points to a function could be useful

1 Like

Btw I’m looking at the template, and it says it works with 4.2. and looking at the git history there have been changes to the binding script between 4.2 and 4.3. so it could be possible that the template used is not compatible with 4.3.

There is also an example project in the template, you could try that with 4.3 to see if it is a template issue.

1 Like

Here’s the github repo: GitHub - LouChiSoft/GDExtension-Template: CMake based GDExtension template

I had a look at the godot_cpp Sconstruct file and didn’t see anything that immediately stood out as something bespoke that needs porting to CMake. I will also check the original template works with 4.3 like you suggest

so it could be possible that the template used is not compatible with 4.3.

Okay, so I think you are right with this. I just built the original template’s extension using the godot-4.3-stable branch in godot-cpp and tried to load it into a Godot application and got an error with the _bind_methods function. I think maybe work asking on the godot-cpp repo at this point?

Um, I don’t think so. I’m pretty sure it works. I recently helped someone setup an audio plugin with gdextension on 4.3 using the default build system.

I think you may want to ask the template creator to take a look.

1 Like

I found the answer, it was due to the differences between FetchContent and ExternalProject. So it wasn’t actually applying the double precision flag, but also not warning it wasn’t doing it. So it was trying to load a single precision extension into a double precision godot instance.

Fixed the FetchContent issue and rebuilt and works fine

1 Like