Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect usage of AddDllDirectory #95905

Closed
0x0ACB opened this issue Aug 21, 2024 · 3 comments · Fixed by #96192
Closed

Incorrect usage of AddDllDirectory #95905

0x0ACB opened this issue Aug 21, 2024 · 3 comments · Fixed by #96192

Comments

@0x0ACB
Copy link
Contributor

0x0ACB commented Aug 21, 2024

Tested versions

4.3

System information

Windows 11

Issue description

Loading GDExtension dll files on Windows does not work if the project has been exported as a .pck file and the .exe is launched from a different folder. This is because AddDllDirectory is called with a relative path and fails. According to the documentation AddDllDirectory needs to be called with an absolute path.

The AddDllDirectory function can be used to add any absolute path to the set of directories that are searched for a DLL.

image

It works if the addons folder is next to the .exe because then LoadLibraryExW gets the correct relative path.

Steps to reproduce

Add GDExtension addon to project
export as .pck
copy the addon folder next to the .pck
place the .exe in a different folder
run the .exe from the folder containing the .pck

Minimal reproduction project (MRP)

|- test.pck
|- addons/
|- bin/
|--test.exe

@0x0ACB 0x0ACB changed the title Incorrect usage of AddDllDirectory Incorrect usage of AddDllDirectory Aug 21, 2024
@0x0ACB 0x0ACB changed the title Incorrect usage of AddDllDirectory Incorrect usage of AddDllDirectory Aug 21, 2024
@0x0ACB 0x0ACB changed the title Incorrect usage of AddDllDirectory Incorrect usage of AddDllDirectory Aug 21, 2024
@dsnopek
Copy link
Contributor

dsnopek commented Aug 23, 2024

Thanks!

Unfortunately, I'm not able to reproduce this.

I tested with Godot v4.3 using the godot-jolt extension and its sample project. When I export, the DLL gets placed in the same folder as the EXE, which loads just fine. Then I tried moving the EXE so that it was in the same path as it was in the project, so I put it under addons/godot-jolt/windows/godot-jolt_windows-x64.dll - this also worked fine!

The only way I could prevent it from being loaded was to put it under some random directory, that wasn't the same as the directory that's specified in the godot-jolt.gdextension file. But it makes sense that it can't load it, because how's it supposed to know which directory its in?

I also re-ran these tests with Godot v4.2.2, and it behaved exactly the same. If the DLL was either next to the EXE, or in the path specified in the godot-jolt.gdextension, then it loads fine. If I put in some arbitrary directory below the EXE, then it doesn't load. So, this doesn't appear to be a regression.

Can you give some more details about how to reproduce? Am I missing a step?

@0x0ACB
Copy link
Contributor Author

0x0ACB commented Aug 25, 2024

Your folder structure is incorrect. But I see now that the diagram I added maybe wasn't that clear about it:

│    launcher.exe
│    game.pck
├─────bin
│     │ game.exe      
│     └────addons
│          └───godot-jolt
│              └───windows
│                  │ godot-jolt_windows-x64.dll

results in platform\windows\os_windows.cpp(383): OS_Windows::open_dynamic_library> Condition "!FileAccess::exists(path)" is true. Returning: ERR_FILE_NOT_FOUND

│    launcher.exe
│    game.pck
├───bin
│   │ game.exe      
│   └── addons
│       └───godot-jolt
│           └───windows
│               │ godot-jolt_windows-x64.dll

results in

<platform\windows\os_windows.cpp(455): OS_Windows::open_dynamic_library> Parameter "p_library_handle" is null.:
Can't open dynamic library: addons/godot-jolt/windows/godot-jolt_windows-x64.dll. Error: Error 126: The specified module could not be found..

Placing the .dll in the same folder as the .exe does indeed work. The call to AddDllDirectory is still incorrect though. We are using a launcher that is started first for updating and the actual game is stored in /bin. Resulting in this slightly unconventional folder structure

@dsnopek
Copy link
Contributor

dsnopek commented Aug 27, 2024

Ah, ok, thanks!

Using that directory structure, I am able to reproduce the issue, and I can confirm that passing an absolute path to AddDllDirectory() fixes it. (I'm simulating having a launcher.exe by launching Godot from cmd.exe with the current directory set to the directory of the launcher.)

Here's PR #96192 which makes that change

@akien-mga akien-mga added this to the 4.4 milestone Aug 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants