I have a Fortran library compiled with gfortran into a DLL. I am trying to call this DLL from python 3.9, and that can work, I can access the expected functions etc so this issue has nothing to do with ctypes etc.
Additionally, I know that the DLL works and can be called from python, another project uses the same DLL but has a flat folder structure (possibly to allow for this issue). However, I need it to be in a python package.
This main DLL has a few dependencies that need to be shipped with it. These dependencies must be in the parent directory of the main DLL (why I have no idea but that is the only way it works).
The issue occurs when trying to use this DLL in my python package.
If the entry point of the python code that calls the DLL is in the parent directory of the DLL then I can access the expected functions, if it is anywhere else I get the following error:
FileNotFoundError: Could not find module 'I:\<full-path>\wrappers\lib\foo.dll' (or one of its dependencies). Try using the full path with constructor syntax.
On the line:
self._libHandle = LoadLibrary(str(self._dll_path))
self._dll_path
is a Path
object with the absolute path to the DLL, I check the file exists before passing it to LoadLibrary
.
I have the following directory structure (additional files removed for brevity):
src
|---entry.py
|---wrappers
| |---lib
| | |---foo.dll
| |---dep1.dll
| |---dep2.dll
| |---foo-wrapper.py
| |---adj-entry.py
If I add some test code to the bottom of foo-wrapper.py
then I can access my DLL, if I import foo-wrapper
into entry.py
, I get the error above. Using the same code from entry.py
in adj-entry.py
works absolutely fine. The test code is shown below.
from src.wrappers import Foo
from pathlib import Path
dll_path = Path("../../src/wrappers/lib/foo.dll").resolve() # This path is the only thing adjusted between entry.py and adj-entry.py. Remove 1 ../ for entry.py
assert dll_path.exists()
assert dll_path.is_file()
f = Foo(dll_path)
What seems to be the only thing that changes is the file that python.exe is actually called with. When the file python is called with is in the DLL's parent directory everything works, if it is anywhere else I get the dependency error.
Does anyone know how I can call this DLL from anywhere? Could this be related to the gfortran build or the Fortran code itself?