I have a fairly simple test project to build a C extension for Python 3.8.8.
the only complexity is that the project is split into two packages:
- one containing a pure C .dll called doubler (which provides a function for doubling a number)
- the other containing a Python extension which links to that .dll and provides a Python interface around it.
I build a .whl for the project and everything installs in the folders I am expecting, but obviously when I try to import the .pyd file it complains that it can't find the .dll (as expected). If I copy the .dll into the folder with the .pyd then it works correctly without issue, but I want to set it up to find the .dll in the other folder using os.add_dll_directory()
.
Unfortunately this is where my problems have begun.
The code listing below shows that I can construct the path to the .dll from site-packages and the name of the package, os.listdir()
shows the package is present. I then call os.add_dll_directory()
on that path, but trying to import hello
gives me the same ImportError
that the .dll can't be found. However if I call ctypes.CDLL()
with the path to the actual .dll file then that succeeds, and I can then import the hello
module because the .dll is now in memory. Am I missing something in how to call os.add_dll_directory()
? Any suggestions about how to resolve this would be appreciated.
>>> import os
>>> import sysconfig
>>> import ctypes
>>> package_folder = os.path.join(sysconfig.get_paths()['platlib'], 'doubler')
>>> dll_path = os.path.join(package_folder, "doubler.dll")
>>> os.listdir(package_folder)
['doubler.dll', 'doubler.lib', 'doublerConfig.cmake', 'doublerTargets-release.cmake', 'doublerTargets.cmake', 'include']
>>> os.add_dll_directory(os.path.join(sysconfig.get_paths()['platlib'], 'doubler'))
<AddedDllDirectory('C:\\...\\anaconda3\\envs\\skbuild\\Lib\\site-packages\\doubler')>
>>> import hello
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\...\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\211.7142.13\plugins\python\helpers\pydev\_pydev_bundle\pydev_import_hook.py", line 21, in do_import
module = self._system_import(name, *args, **kwargs)
File "C:\...\anaconda3\envs\skbuild\lib\site-packages\hello\__init__.py", line 1, in <module>
from ._hello import hello # noqa: F401
File "C:\...\AppData\Local\JetBrains\Toolbox\apps\PyCharm-P\ch-0\211.7142.13\plugins\python\helpers\pydev\_pydev_bundle\pydev_import_hook.py", line 21, in do_import
module = self._system_import(name, *args, **kwargs)
ImportError: DLL load failed while importing _hello: The specified module could not be found.
>>> ctypes.CDLL(dll_path)
<CDLL 'C:\...\anaconda3\envs\skbuild\Lib\site-packages\doubler\doubler.dll', handle 7ffbeff50000 at 0x2237dc6a0d0>
>>> import hello
>>> hello.double_number(4)
8