Open S3B4S opened 4 years ago
Some more information as I had 2 teammates reproduce the error, one is on MacOS, the other is on Windows. The person on MacOS is not able to reproduce the error, they follow the same steps I did and it's successfully working for them. They've also cloned the project that I was working on and that is also still working for them. The other person on Windows does run into the same error that I do. So I'm starting to think it might have to with either the environment or build tools.
So some information regarding this environment;
scons platform=windows
. Setting the environment to x64.By now I've attempted to do this with CMake, but that unfortunately results in the exact same issue as described above.
The CMakeLists.txt
is in a build/
directory that has been added to the root of the repo (structure still same as the example repo).
Steps to reproduce
cd build/
cmake .
.dll
with additional files, copy all of those over to <godot-project>/bin/win64/
CMakeLists.txt:
cmake_minimum_required(VERSION 3.1...3.15)
if(${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
# set the project name
project(TouchThaBomb VERSION 0.1
DESCRIPTION "Defuse bomb game with hand tracking"
LANGUAGES CXX)
# https://cmake.org/cmake/help/latest/command/find_package.html#search-procedure
find_package(OpenCV 4.3 EXACT REQUIRED PATHS /OpenCV/opencv-4.3.0-vc16/)
include_directories(AFTER "${OpenCV_INCLUDE_DIRS}" "include")
link_libraries(${OpenCV_LIBS})
link_libraries("../godot-cpp/bin/libgodot-cpp.windows.debug.64")
# create the .dll
#file(GLOB source_list "src/*.h" "src/*.cpp")
add_library(libgdexample SHARED "../src/gdexample.cpp" "../src/gdlibrary.cpp")
include_directories(
"../godot-cpp/godot_headers/"
"../godot-cpp/include/"
"../godot-cpp/include/core/"
"../godot-cpp/include/gen/"
"../godot-cpp/bin/"
)
When my code only includes the opencv libraries, it will compile and run fine in Godot; But when I do want to use a method from the imported code (so it's the exact same code snippet as above, but the Mat image = Mat::zeros(300, 600, CV_8UC3); line is uncommented), I run into the following error:
Remains the exact same, the error is as follows:
ERROR: Can't open dynamic library: C:/Users/kevin/Development/contextproject/Godot/bin/win64/libgdexample.dll, error: Error 126: The specified module could not be found.
.
At: platform/windows/os_windows.cpp:2269
ERROR: get_symbol: No valid library handle, can't get symbol from GDNative object
At: modules/gdnative/gdnative.cpp:483
ERROR: init_library: No nativescript_init in "res://bin/win64/libgdexample.dll" found
At: modules/gdnative/nativescript/nativescript.cpp:1506
ERROR: _update_placeholder: Condition "!script_data" is true.
At: modules/gdnative/nativescript/nativescript.cpp:92
ERROR: _update_placeholder: Condition "!script_data" is true.
At: modules/gdnative/nativescript/nativescript.cpp:92
Running: D:\Program Files (x86)\Godot\Godot_v3.2.1-stable_mono_win64.exe --path C:/Users/kevin/Development/contextproject/Godot --remote-debug 127.0.0.1:6007 --allow_focus_steal_pid 5300 --position 768,420
Godot Engine v3.2.1.stable.mono.official - https://godotengine.org
OpenGL ES 3.0 Renderer: AMD Radeon RX 5700 XT
Mono: Logfile is: C:\Users\kevin\AppData\Roaming/Godot/mono/mono_logs/2020_05_18 19.09.43 (9464).txt
ERROR: Can't open dynamic library: C:/Users/kevin/Development/contextproject/Godot/bin/win64/libgdexample.dll, error: Error 126: The specified module could not be found.
.
At: platform/windows/os_windows.cpp:2269
ERROR: get_symbol: No valid library handle, can't get symbol from GDNative object
At: modules/gdnative/gdnative.cpp:483
ERROR: init_library: No nativescript_init in "res://bin/win64/libgdexample.dll" found
At: modules/gdnative/nativescript/nativescript.cpp:1506
For some reason it can't open the DLL that is created:
ERROR: Can't open dynamic library: C:/Users/kevin/Development/contextproject/Godot/bin/win64/libgdexample.dll, error: Error 126: The specified module could not be found. Both in this version and your original version. The rest of the errors are flow on effects.
Assuming it has compiled the DLL and it is placed in that folder, it could be that it can't load OpenCV itself as a dependency. You need to make sure the opencv dll(s) are also placed in the bin/win64 folder and that you name those dlls in your gdnlib file in the dependencies section
Hey, thanks for responding.
We're actually not including any opencv dll(s), we're including .lib
files instead, from my understanding these files should be inlined in the created libgdexample.dll
right? Or should we also include the opencv dll(s) as found in <path-to-opencv>/bin/
?
For ease, I've uploaded the project that I'm using to reproduce this. https://github.com/S3B4S/opencv-gdnative/tree/gdnative. In the repository I've added a example-opencv-dependency.txt file that shows the structure of the opencv (4.3.0) dependency so you can see what I'm talking about.
Though, by now I'm running in a new error that might provide more information. If I try to include an additional line in gdexample.cpp
(this one: https://github.com/S3B4S/opencv-gdnative/blob/gdnative/src/gdexample.cpp#L34). I get the following error:
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
link /nologo -DEBUG /dll /out:Godot\bin\win64\libgdexample.dll /implib:Godot\bin\win64\libgdexample.lib /LIBPATH:godot-cpp\bin /LIBPATH:D:\OpenCV\opencv-4.3.0-vc16\build\lib libgodot-cpp.windows.debug.64.lib opencv_calib3d430.lib opencv_core430.lib opencv_dnn430.lib opencv_features2d430.lib opencv_flann430.lib opencv_gapi430.lib opencv_highgui430.lib opencv_imgcodecs430.lib opencv_imgproc430.lib opencv_ml430.lib opencv_objdetect430.lib opencv_photo430.lib opencv_stitching430.lib opencv_video430.lib opencv_videoio430.lib src\gdexample.obj src\gdlibrary.obj
Creating library Godot\bin\win64\libgdexample.lib and object Godot\bin\win64\libgdexample.exp
gdexample.obj : error LNK2019: unresolved external symbol "void __cdecl cv::circle(class cv::debug_build_guard::_InputOutputArray const &,class cv::Point_<int>,int,class cv::Scalar_<double> const &,int,int,int)" (?circle@cv@@YAXAEBV_InputOutputArray@debug_build_guard@1@V?$Point_@H@1@HAEBV?$Scalar_@N@1@HHH@Z) referenced in function "public: void __cdecl godot::GDExample::_init(void)" (?_init@GDExample@godot@@QEAAXXZ)
Godot\bin\win64\libgdexample.dll : fatal error LNK1120: 1 unresolved externals
scons: *** [Godot\bin\win64\libgdexample.dll] Error 1120
scons: building terminated because of errors.
So usually this means that it cannot find certain header files and/or libraries from my understanding, but I cannot find what I'm missing here. I think I've set it up fine in the SConstruct.
I've also set up a seperate project with only opencv, using Visual Studio and when I set these same locations it worked fine when building with Visual Studio. (For more information on how I did this project, I followed the steps described here).
So I don't feel like there's something wrong with the locations themselves, however I might miss something else that's needed for building a .dll
perhaps?
That all depends on whether you've compiled OpenCV as a static library or not. If it is compiled as a static library the .lib file contains all. If you've compiled it as a dynamic library the .lib file only contains the glue that allows you to use the OpenCV dll and the dll needs to be included.
The new error you're getting means that you are calling the circle function in the OpenCV library but that it doesn't know this function. That suggest the library file isn't being included correctly. Makes no sense though, from what I understand circle is a core function of OpenCV and you are including the core library.. Unless there is some other reason it skips that code in the SConstruct file..
Okay that was insightful, since the libraries I'm using are pre-built ones downloaded from here, so I went and checked if they were dynamic or static by running lib /list <name>.lib
on one of the libs (source: https://stackoverflow.com/questions/6402586/know-if-lib-is-static-or-import)
So running
$ lib /list opencv_calib3d430.lib
gave me the output of
opencv_calib3d430.dll
... 814 times 😆.
I think it seems fair to conclude then that this means these .lib
's are dynamic as you mentioned it, and I'd need to include all the .dll
files as referenced by the .lib
files in win64/bin/
and declare them as dependencies.
The circle not being found is indeed very strange, I will keep digging around about that, in any case I wanted to report above findings.
Regarding the "circle function not being found", when I build with CMake this issue does not appear. I'm succesfully able to build the same source files. So with this out of the way, I tried to see if adding the .dll
files found in the OpenCV bin/
and declaring them as dependencies would do the trick:
.dll
files to win64/bin/.gdnlib
https://github.com/S3B4S/opencv-gdnative/blob/gdnative/Godot/bin/gdexample.gdnlib#L17-L34But unfortunately, the error still remains 🤔
Oh, I hadn't realised there was an issue opened for this here too.
FYI, I replied to your other issue in case it's still useful: https://github.com/godotengine/godot-cpp/issues/403#issuecomment-641349888
I've also subsequently discovered that GDNative does its own (redundant?) dynamic library path manipulation before calling the open_dynamic_library()
function.
I've also discovered what appears to be an edge case problem that occurs if you try to run an exported .exe
while it's in the root of your project structure (or equivalent location or if you're using the CLI to run the exe while the current directory is the project? (I'm still confirming the exact situation)) due to this check:
AFAICT the !FileAccess::exists(path)
check shouldn't occur in exported executables because it can access paths that the (Windows OS) DLL loading code is...unaware of, I guess.
I think if the path is converted to an absolute path first then both entities would see things the same way--but that may have its own issues.
Anyway, I only mention that here because it was a bizarre scenario where I knew I'd had a particular executable run & find its DLL dependencies previously but now it couldn't--and it turned out to be related to now being in the project directory on the command line.
Given all this, I'd recommend you use a file access logging tool to find out what paths are actually being accessed. Since I was doing this investigation on a Mac with WINE (it's a long story... :D ) I was able to use opensnoop
, a DTrace
-based tool.
TLDR: Same issue here on Godot 3.3.4 when trying to call a method of DiscordGameSDK from a C++ gdnative project. It works fine if I define any variable which is of a type from the DiscordGameSDK but as soon as I try to call any method from it I get the same error "cant open dynamic library..." in the Godot editor.
Godot version: 3.3.4 godot-cpp: Branch 3.3 OS/device including version: Windows 10 x64 21H1 19043.1415
I get the error "Cant open dynamic library" in the Godot editor only when the c++ project trys to call any method from discord_Game_sdk. [attached godot project files] Gdnative_cpp_project.zip
Godot version: 3.2.1
OS/device including version: Windows 10, build 1903
The issue
Hey, I hope I'm in the right place with this, I've followed the example in the docs for c++: https://docs.godotengine.org/en/stable/tutorials/plugins/gdnative/gdnative-cpp-example.html. This went all right, my next step was to include opencv, so I appended additonal locations to
CPPPath
,LIBPATH
andLIBS
in SConstruct: https://github.com/S3B4S/opencv-gdnative/blob/gdnative/SConstruct#L165-L184When my code only includes the opencv libraries, it will compile and run fine in Godot (below example would have modified
src/gdexample.cpp
in the example repository);But when I do want to use a method from the imported code (so it's the exact same code snippet as above, but the
Mat image = Mat::zeros(300, 600, CV_8UC3);
line is uncommented), I run into the following error:I'm honestly confused by the fact that it's saying it cannot find
libgdexample.dll
anymore, it's definitely there. When the lines that includeOpenCV
are commented out it does find the.dll
file.I'm new to this kind of stuff, so I'm not sure if I've overlooked something or that this is unexpected behaviour.
Additional information in case it's needed
I've pushed the project I'm working on to here.
Steps to reproduce:
Assuming that OpenCV is installed &
OPENCV_DIR
environment variable is set.scons platform=windows
, this should output alibgdexample.dll
among other files in<Godotproject>/bin/win64