godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.69k stars 527 forks source link

Virtual function with Node* argument - Undefined Symbol Under Linux #1480

Closed Kehom closed 3 months ago

Kehom commented 3 months ago

Godot version

4.3 beta 1

godot-cpp version

master

System information

Windows 10 and Linux Mint

Issue description

I'm not sure if I'm setting up something incorrectly or not. Nevertheless, if I declare a virtual function that contains an argument that is a pointer to Node or any derived class, then Godot fails to load the extension under Linux, telling that there is undefined symbol GetTypeInfo??WhateverArgumentType. Yet it does work fine under Windows (using MS compiler - was unable to compile using MingW).

Just to make sure the error was indeed related to the argument type within the GDVIRTUAL macro, I changed the argument type to Variant and errors went away.

Steps to reproduce

GDVIRTUAL1(_some_virtual_function, godot::Control*);

It should result in Undefined symbol ???godot??GetTypeInfo???Control?METADATAE The "?" above are artifacts of the compiler.

Minimal reproduction project

-

AThousandShips commented 3 months ago

Did you also bind it in the code? You can't just add GDVIRTUAL you also need to add GDVIRTUAL_BIND(_some_virtual_function, "arg"); to _bind_methods

Kehom commented 3 months ago

Yes, I did add the GDVIRTUAL_BIND(). Sorry I forgot to mention that. But then, without it I don't think the code would have worked under Windows or with Variant instead of anything derived from Node*.

Again, I might have messed up something in the setup. Yet, because the code does work when not using Node* (or derived) as argument type, I suspect there is something else at play.

AThousandShips commented 3 months ago

Does it work if you do ::Godot::Control?

Kehom commented 3 months ago

Unfortunately no. It's the exact same behavior. Compilation goes OK, but when attempting to open the project comes the undefined symbol error message. It does work very fine with either GDVIRTUAL1(_some_virtual, godot::Variant) or GDVIRTUAL1(_some_virtual, ::godot::Variant) or GDVIRTUAL1(_some_virtual, const godot::Variant&).

One thing to note, if I declare a function to return a pointer to Node* or anything derived, then it will work as long as there isn't any argument with such type.

Inspecting the macro for the declaration of a function with no return and a single argument, there is this:

method_info.arguments.push_back(::godot::GetTypeInfo<m_type1>::get_class_info());\
method_info.arguments_metadata.push_back(::godot::GetTypeInfo<m_type1>::METADATA);

Since the undefined symbol message always contains GetTypeTypeInfo I suspect there is something going on related to GetTypeInfo<Control*> (or anything derived from Node).

dsnopek commented 3 months ago

I can reproduce this error!

I just posted PR https://github.com/godotengine/godot-cpp/pull/1484 which fixes this in my testing. Please let me know if it works for you!