godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.34k stars 21.06k forks source link

reinterpret_cast Error in VisualStudio22 / C++ Extension / ClassDB::bind_method(...) #87199

Closed TinoNug closed 5 months ago

TinoNug commented 9 months ago

Tested versions

Reproduceable in 4.2 stable. System information

System information

Windows 10, v4.2 table Issue description

Issue description

reinterpret_cast in create_method_bind is not working in VS22 compiler.

I tried every SDK, Platformtoolset and C++ Lang back to 2017. Compiler is just not having it.

Error:

error C2440: "reinterpret_cast": cannot convert from "void (__cdecl godot::MyCanvasLayer::* )(void) const" to "void (__cdecl godot::_gde_UnexistingClass::* )(void) const"

godot::ClassDB::bind_method<godot::MethodDefinition,void(__cdecl godot::MyCanvasLayer:: )(void) const,>(N,M)" der Funktions-Vorlage.
1> with
1> [
1> N=godot::MethodDefinition,
1> M=void (__cdecl godot::MyCanvasLayer::* )(void) const
1> ]
1> C:\Development\Godot\Projekte\SDKs\godot\include\godot_cpp\core\class_db.hpp(246,21):

Function:

File: godot\include\godot_cpp\core\method_bind.hpp

template <class T, class... P>
MethodBind *create_method_bind(void (T::*p_method)(P...) const) {
#ifdef TYPED_METHOD_BIND
MethodBind *a = memnew((MethodBindTC<T, P...>)(p_method));
#else
MethodBind a = memnew((MethodBindTC<P...>)(reinterpret_cast<void (MB_T::)(P...) const>(p_method)));
#endif // TYPED_METHOD_BIND
a->set_instance_class(T::get_class_static());
return a;
}

Steps to reproduce

LastJourney_3D_err.zip

You should be able just to build the added project with VisualStudio Community.

Examle from https://github.com/godotengine/godot-cpp-template has also the same issue.

Minimal reproduction project (MRP)

LastJourney_3D_err.zip

The Godot source code compiled for Windows should be inserted by you: (Too big to upload)

LastJourney_3D_err\godot

(https://docs.godotengine.org/en/stable/tutorials/scripting/gdextension/gdextension_cpp_example.html#setting-up-the-project)

bruvzg commented 9 months ago

added project with VisualStudio Community

What's the source of this VS project? godot-cpp template project use SCons build system, and your project doesn't seem to call code generation script or include any of the generated files.

TinoNug commented 9 months ago

Hey,

I have uploaded the entire project + dependencies and compiled code of godod to this folder:

https://drive.google.com/file/d/15pwMJSbDOGDRjV6hch9T7844WLjKHtR6/view?usp=sharing

Godot is compiled with SCons. Paths in VS are relative, so it should just fire up.

So far, everything works in VS. But the binding does not work. I tried to change the code, but to be honest ... it looks like voodoo to me. :D

Is it possible for you to download it? Should be enough to open the solution and compile it.

grafik

bruvzg commented 9 months ago

You do not need to compile Godot to build your GDExtension, you need godot-cpp (and you do not need to build it separately), and unlike Godot it's not supporting building with VS project you need to use Scons.

Screenshot 2024-01-18 at 10 00 12
TinoNug commented 9 months ago

I dont unterstand.

I do not compile godot in VS.

I only compile my extension.lib. I use godot only as a library.

grafik grafik

But because the compiler checks the code in the included (godot) headers, I get the error. So VS cant compile my lib because of the cast in function "method_bind.hpp -> ClassDB::bind_method(D_METHOD(...." .

I will try a few things but, I dont think I can do much about it other then compile my lib with another compiler.

It works in VSCode with scons. So I suspect that it is a problem with the Windows compiler.

In VS, the name of the lib folder is not important. This is because you set it up yourself in the inlucde section of the project. I just named the folder ..\godot.

BTW: Everything else works fine in VS. I can debug everything without any problems. So far, I love it.

whiletrue111 commented 6 months ago

did you find solution , im working with vc++ 2022 ..

ghost commented 6 months ago

Not really. I accidentally opened 2 threads. Here is another thread:

https://github.com/godotengine/godot/issues/87198#issuecomment-1953706861

CatShot112 commented 6 months ago

I found a solution, you have to define TYPED_METHOD_BIND. Project Settings -> C/C++ -> Preprocessor -> Preprocessor definitions

Reference: Line 167 in CMakeLists.txt in godot-cpp repo. (4.2)

TinoNug commented 5 months ago

I can confirm. It works. Signals are working now.

Thank you @CatShot112 !!

TinoNug commented 5 months ago

@CatShot112 found a solution:

define TYPED_METHOD_BIND Project Settings -> C/C++ -> Preprocessor -> Preprocessor definitions

Lycoris-SF commented 4 months ago

May I ask what kind of black magic is this? I'v completely lose my sanity.

whiletrue111 commented 4 months ago

@TinoNug @CatShot112
How did you create visual studio c++ sln project ? Currently im using only scons and "open directory" from VC++ . I like to be able to create native VSC++ sln project ..

CatShot112 commented 4 months ago

@whiletrue111

It's more or less as follows:

  1. Clone repo: https://github.com/godotengine/godot-cpp -b 4.2

  2. Open x64 Native Tools Command Prompt for VS 2022

  3. Navigate to cloned repo (godot-cpp)

  4. Run command: mkdir build && cd build && cmake ..

  5. Open generated solution file (.sln) located in created build folder

  6. Now to make things build faster you can enable multi-threaded compilation and disable exceptions as godot has them disabled. Right-click project -> Properties C/C++ -> General -> Multi-processor Compilation -> Yes (/MP) C/C++ -> Code Generation -> Enable C++ Exceptions -> No

  7. Build Debug then Release (x64)

  8. Open Visual Studio Community and create empty C++ project (You can remove x86/Win32 as godot is x64)

  9. Make sure to set build type to .DLL and set C++ standard to c++17 Right-click project -> Properties General -> Configuration Type C/C++-> Language -> C++ Language Standard

  10. Open project location in explorer and create folders: src, include, lib

  11. Copy godot-cpp/include/godot-cpp folder to /include

  12. Copy godot-cpp/build/gen/include/godot-cpp to /include

  13. Copy godot-cpp/gdextension/gdextension_interface.h to /include

  14. Copy godot-cpp/build/bin/[Debug,Release] to /lib

  15. Now you need to add include and lib path to project settings. Right-click project -> Properties VC++ Directories -> Include Directories -> Arrow -> -> Paste: $(ProjectDir)include VC++ Directories -> Library Directories -> Arrow -> -> Paste: $(ProjectDir)lib\$(Configuration)

  16. Define TYPED_METHOD_BIND Project Settings -> C/C++ -> Preprocessor -> Preprocessor definitions

  17. Create RegisterTypes.hpp and RegisterTypes.cpp with default content from the wiki.

  18. It should build fine.

I might have missed something, if so let me know :)

Maybe i will make some tutorial where i set-up and configure everything from scratch.

whiletrue111 commented 4 months ago

Hey thanks allot ! one more question how can i configure from within the VSC++ to use : https://github.com/godotengine/godot-cpp-template to use this dll , be able to run it also as sln ? is it possible . And also keep the functionally of the lanch.vs.json . Example of project :

{
 "version": "0.2.1",
 "defaults": {},
 "configurations": [
  {
   "type": "default",
   "project": "C:\\dev\\my\\godot\\Godot_v4.2.1-stable_win64.exe\\Godot_v4.2.1-stable_win64.exe",
   "name": "Godot Game",
   "args": [ "--windowed", "--resolution 700x1000","--path", "c:\\dev\\my\\godot\\godotcpp\\2d\\TappyPlan\\godot-cpp-template-ready\\demo" ]
  },

  {
   "type": "default",
   "project": "C:\\\\dev\\\\my\\\\godot\\\\Godot_v4.2.1-stable_win64.exe\\\\Godot_v4.2.1-stable_win64.exe",
   "name": "Godot Editor",
   "args": [ "c:\\dev\\my\\godot\\godotcpp\\2d\\udemy\\godot-cpp-template-ready\\demo" ]
  }
 ]
}
CatShot112 commented 4 months ago

@whiletrue111 If I understood correctly, you want to debug your godot project from Visual Studio?

Project Settings -> Debugging -> Command -> (path to your godot.exe) Project Settings -> Debugging -> Command Arguments -> (your command line arguments)

Example: Command: C:\dev\my\godot\Godot_v4.2.1-stable_win64.exe\Godot_v4.2.1-stable_win64.exe

Command Arguments: --windowed --resolution 700x1000 --path c:\dev\my\godot\godotcpp\2d\TappyPlan\godot-cpp-template-ready\demo

I also suggest putting path to the scene you want to debug after arguments, ex. res://Main.tscn

Edit: Make sure you copied compiled .dll file to your project before debugging. You can create custom post-build event so Visual Studio will do it automatically. Project Settings -> Build Events -> Post-Build Event -> Command Line -> xcopy /y /d "$(OutDir)$(ProjectName).dll" path