2

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
applesomthing
  • 361
  • 3
  • 19

1 Answers1

0

Maybe this could be your solution:
https://stackoverflow.com/a/60803169/19344391

Check if your dll depends on other dlls. If that's your case, you might be able to load it by adding all the directories that contain those dlls.

pjueon
  • 1
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 22 '22 at 03:21