godotengine / godot-cpp

C++ bindings for the Godot script API
MIT License
1.68k stars 509 forks source link

Win10 VS2015-built DLL: Fails to load GDNativeLibrary #14

Closed willnationsdev closed 7 years ago

willnationsdev commented 7 years ago

Context: Windows 10 Visual Studio 2015 Community Edition Godot latest as of commit ceded65 from 06/20/2017 Having just compiled a .dll in visual studio (walkthrough in this issue from /cpp_bindings.

Issue: Built the cpp_bindings tutorial SimpleClass into the .dll. SimpleClass has no parent class it inherits from as far as the scripting language is concerned (?). Attempting to load the .gdn resource after setting it to point towards the .tres of the GDNativeLibrary appears to fail with the following errors:

EDIT: Correction, this is the actual error (I copy/pasted this from an Issue in godot_headers, my bad) Can't open dynamic library: [path to project_folder/gdtestdll.dll]. Error: 126 END EDIT

Can't open dynamic library: [path to project_folder/lib/gdtestdll.dll] Error: 126 Condition ' initialize_status != OK ' is true. Condition ' !native_library->scripts.has(p_name) ' is true. returned: 0 Condition ' !script_data ' is true.

Reproducible Steps:

Created a project that literally just throws everything into the root godot project directory. I have the following:

.import (folder) default_env.tres gdtestdll.dll gdtestdll.exp gdtestdll.ilk gdtestdll.lib gdtestdll.pdb gdtestdll.tres godot_cpp_bindings.dll godot_cpp_bindings.exp godot_cpp_bindings.lib godot_cpp_core.dll godot_cpp_core.exp godot_cpp_core.lib icon.png icon.png.import main.tscn project.godot SimpleClass.gdn

main.tscn has a single Node2D with a Built-in GDScript that simply preload's "res://SimpleClass.gdn"

extends Node2D var SimpleClass = preload("res://SimpleClass.gdn")

SimpleClass.gdn has Class Name "SimpleClass" and is pointing to res://gdtestdll.tres which in turn has its Windows value set to res://gdtestdll.dll

I set the default GDNativeLibrary in Project Settings to be res://gdtestdll.tres.

Despite all of that, it's still unable to "locate the module" as per Error 126 in Visual Studio

RameshRavone commented 7 years ago

You have to place your library under lib folder

RameshRavone commented 7 years ago

You might want to look at, http://frogsquare.com/post/160868714645/gdnative-tutorial-cpp

karroffel commented 7 years ago

@RameshRavone for Windows the godot_cpp_*.dll files need to be in the Godot project root. But other than that, wow, cool tutorial!

Also he said he set the lib path to res://gdtestdll.dll

RameshRavone commented 7 years ago

Can't open dynamic library: [path to project_folder/lib/gdtestdll.dll] well this line clearly states that it checks under lib folder. Well I had this same problem when I placed it under the root folder, yes I set the lib path to res://libgodot_ai.so. May be its a linux thing.

karroffel commented 7 years ago

Oh yeah, maybe he needs to double check the GDNativeLibrary paths

willnationsdev commented 7 years ago

Oh, that's my bad. I'll edit the original post soon. I was copy/pasting it all from an Issue I'd incorrectly put in the godot_headers repo and in that one I had originally had a lib folder. I will post the actual error I see in my current project in a half-hour.

To be clear, in my current project, I have every file in the root directory, all paths point to the appropriate file in my root directory, and the error I am seeing is looking for a file in my root directory. My apologies for the confusion.

willnationsdev commented 7 years ago

Man, I WISH the windows tutorial were that easy (as the tutorial you linked). Unfortunately, I have to use visual studio because I'm not really sure how to use any cmd compilers on windows (though I've learned g++ for Linux). Once I figure this out though, it'd be worth it to make another Issue with a MinGW attempt since that would simplify the workflow a lot (would just need to figure out the command line operations).

willnationsdev commented 7 years ago

Ok, made the correction.

I'm going to go ahead and zip up my project root folder and post it here...

GDNativeTest.zip

karroffel commented 7 years ago

Maaaaybe you need the .lib file that you used to build the bindings too.

willnationsdev commented 7 years ago

You mean the godot.windows.opt.tools.64.lib file? I just tried adding it to the project root directory, and it didn't make a difference.

willnationsdev commented 7 years ago

Is there any reason that godot would need GDNativeLibraries for the other .dll's? (I wouldn't think so, but...)

willnationsdev commented 7 years ago

Has there been any updates in the last month on forming a consensus as to an updated implementation of the godot.windows.opt.tools.64.lib or equivalent? Last I tried, the engine couldn't find the .dll pointed to by the GDNativeLibrary .tscn file and I believe that my having an outdated version of that opt.tools .lib is what might have been causing it. I just can't really test whether that was the issue until I get a copy of an updated implementation...

RameshRavone commented 7 years ago

wait, godot.windows.opt.tools.64.lib is created when you compile godot master branch, with MSVC I think

willnationsdev commented 7 years ago

Not in mine...? I pulled that file from the gdnative starter kit zip that was inside of the original GDNative blog post on the Godot blog. Searching my /godot folder (from my VS2015 build) for anything with 'opt.tools' in the name doesn't bring up the lib file in my Windows Explorer, so it doesn't seem like it's there either.

RameshRavone commented 7 years ago

I do have one from Jul 7, may be I can send you that,

willnationsdev commented 7 years ago

Yeah, that'd be great if you could send it here. I can just download it then, try it, and get back to you. Probably later though. I'm busy this weekend.

RameshRavone commented 7 years ago

godot.windows.opt.tools.64.lib

RichyHBM commented 7 years ago

@willnationsdev Did you manage to fix this? I had the same error and got it working if you still need a hand

willnationsdev commented 7 years ago

I haven't tried it out yet with the latest stuff! I should go ahead and try that in a few minutes. If I can't get it to work like before, I would greatly appreciate you providing a written guide on what you did to get things working properly.

RichyHBM commented 7 years ago

I'll lay it out here regardless, it may help others. So the main issue I saw was coming from using different versions of the editor for compiling and linking.

My final solution was to download the godot source, compile it in debug, then download the godot_headers and cpp_binding and compile these, now you should have correct libraries for the editor version. then you just compile your code linking to these and the editor should pick it up correctly. For a list of commands that I used:

mkdir godot cd godot mkdir deps cd deps git clone https://github.com/GodotNativeTools/cpp_bindings.git git clone https://github.com/GodotNativeTools/godot_headers.git git clone https://github.com/godotengine/godot.git godot_fork cd godot_fork scons p=windows cd ../cpp_bindings scons p=windows generate_bindings=yes cd ../.. //compile your own code, for me that is using cmake cd build cmake -G "Visual Studio 15 2017 Win64" ../src cmake --build . --config Debug

If it helps, here is an example CMake file

cmake_minimum_required (VERSION 3.1)
project (MyLib)

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin)

IF(NOT CMAKE_BUILD_TYPE)
    SET(CMAKE_BUILD_TYPE "Debug")
ENDIF(NOT CMAKE_BUILD_TYPE)

include_directories(
  "${PROJECT_SOURCE_DIR}"
  "${PROJECT_SOURCE_DIR}/../deps/cpp_bindings/include"
  "${PROJECT_SOURCE_DIR}/../deps/godot_headers"
  "${PROJECT_SOURCE_DIR}/../deps/cpp_bindings/include/core"
)

link_directories(
  "${PROJECT_SOURCE_DIR}/../deps/godot_fork/bin"
  "${PROJECT_SOURCE_DIR}/../deps/cpp_bindings/bin"
)

add_library("${PROJECT_NAME}" SHARED
  "${PROJECT_SOURCE_DIR}/init.cpp"
)

target_link_libraries("${PROJECT_NAME}" "godot_cpp_bindings" "godot.windows.tools.64")
willnationsdev commented 7 years ago

@RichyHBM I tried doing the compilation using the alpha1 release content (literally just threw everything directly into my VS2015 project directory next to my init.cpp file). So, it looks like this:

godot
godot_cpp
gdnativedll.vcxproj
gdnativedll.vcxproj.filters
godot.windows.opt.64.lib
godot_cpp_bindings.lib
godot_nativescript.h
init.cpp

The init.cpp has the content from the README.md file on GitHub. Having Includes point to godot and godot_cpp, the libraries point to the project directory, and the Linker > Input > Additional Dependencies list godot.windows.opt.64.lib and godot_cpp_bindings.lib. Compiling still leaves me with this weird linking error about a detected mismatch of debug symbols:

LNK2038 mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2' in init.obj

Do you have any idea what might be causing that?

RichyHBM commented 7 years ago

The opt.64.lib file is a release build whereas the cpp_binding lib I believe is a debug (as I assume is your build?) I would highly recommend just building the libraries yourself as this stage

willnationsdev commented 7 years ago

Yeah, I recently just started over from scratch with the new documentation and after some back and forth with @karroffel, I managed to figure it out. To summarize:

  1. Assuming you already have a godot fork setup and built using the "Compile Godot on Windows" guide.
  2. I clone the cpp_bindings and godot_headers repos
  3. Update the SConstruct file in cpp_bindings to have godot_bin and godot_lib point to the godot fork's /bin folder.
  4. From within cpp_bindings, in a command line, run scons p=windows generate_bindings=yes
  5. Create a new Win32 Application VS project with DLL and Empty checked.
  6. Create an init.cpp file with contents copy/pasted from the GitHub README.md example and add it to the Source Files section of the Solution Explorer.
  7. Edit Project Settings with All Platforms / All Configurations selected at the top.
  8. Add to VC++ Directories > Include Directories: godot_headers, cpp_bindings/include, and cpp_bindings/include/core
  9. Add to VC++ Directories > Library Directories: cpp_bindings/bin AND the godot/bin (of your godot fork - which I was NOT doing earlier)
  10. Edit Linker > Input > Additional Dependencies: godot_cpp_bindings.lib AND godot.windows.tools.64.lib
  11. Hit Build > Build Solution / F6, etc.

For me, that ended up successfully building the solution.

I then tried to create a GDNativeLibrary resource and, after it was made, created a .gdns NativeScript that pointed to the GDNativeLibrary with Inherits=Reference and ClassName=SimpleClass. That ended up working and, after editing the register_methods section and re-loading the C++ script, I could call the test_void_method() function that prints to the output successfully, WITHOUT having to close/re-open the editor. So I can confirm that everything works now.

Edit:

Forgot to also mention that godot_lib needs to be modified in cpp_bindings\SConstruct