Reputation: 287
I've been stressin for a few days trying to compile a modified version of libuvc on windows and now that I've finally done it, I can't seem to load it on Python. This lib that I've already compiled and successfully imported using the same version of Python on Linux machines, doesn't like w10 at all.
System
Problem
When trying the
import ctypes
import ctypes.util
name = ctypes.util.find_library('libuvc')
lib = ctypes.cdll.LoadLibrary(name)
I get the following error:
Could not find module 'C:\Program Files (x86)\libuvc\lib\libuvc.dll'.
Try using the full path with constructor syntax.
Error: could not find libuvc!
The issue is that the file exists since it was found by util.find_library, but python doesn't think it is where it is, or maybe the output is just the default. What am I missing here? What could be failing to be unable to not just load the module, but find it? I'm sorry I don't have more output than this.
P.S: I've tried reformatting the string in different ways, but the message doesn't change.
Upvotes: 25
Views: 69320
Reputation: 41116
Starting with Python 3.8, the .dll search mechanism has changed (Win specific).
According to [Python.Docs]: os.add_dll_directory(path) (emphasis is mine):
Add a path to the DLL search path.
This search path is used when resolving dependencies for imported extension modules (the module itself is resolved through sys.path), and also by ctypes.
...
Availability: Windows.
So, you could do:
os.add_dll_directory("${path_to_working_dlls_directoy}")
where ${path_to_working_dlls_directoy} is a placeholder for the actual path and it (obviously) should be replaced by it.
You can check [SO]: PyWin32 and Python 3.8.0 (@CristiFati's answer) (which although it seems very different, has the same cause), for more details.
P.S.: Nix OSes are not impacted.
While I based my answer on (official) documentation, [SO]: Can't import dll module in Python (@MadPhysicist's answer) (great answer BTW) came with the why part.
However, there are some aspects that need to be clarified.
Everything I stated about os.add_dll_directory is correct and still applies. According to [MS.Learn]: LoadLibraryExA function (libloaderapi.h) (emphasis is mine):
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
0x00001000This value is a combination of LOAD_LIBRARY_SEARCH_APPLICATION_DIR, LOAD_LIBRARY_SEARCH_SYSTEM32, and LOAD_LIBRARY_SEARCH_USER_DIRS. Directories in the standard search path are not searched. This value cannot be combined with LOAD_WITH_ALTERED_SEARCH_PATH.
This value represents the recommended maximum number of directories an application should include in its DLL search path
LOAD_LIBRARY_SEARCH_USER_DIRS
0x00000400If this value is used, directories added using the AddDllDirectory or the SetDllDirectory function are searched for the DLL and its dependencies.
This is the mechanism used by default (winmode=None
, as LOAD_LIBRARY_SEARCH_DEFAULT_DIRS is passed to LoadLibraryEx).
When setting winmode=0
, Win default search mechanism kicks in. [MS.Learn]: Dynamic-Link Library Search Order - Standard Search Order for Desktop Applications states (last item - regardless of SafeDllSearchMode, emphasis still mine):
- The directories that are listed in the PATH environment variable. Note that this does not include the per-application path specified by the App Paths registry key. The App Paths key is not used when computing the DLL search path.
I prepared a small example.
Python code attempts to load (via CTypes) dll00.dll located in the same dir, which in turn is linked to (depends on) another one (dll01.dll) located in a different dir (subdir00).
dll00.c:
#include <stdio.h>
#if defined(_WIN32)
# define DLL00_EXPORT_API __declspec(dllexport)
#else
# define DLL00_EXPORT_API
#endif
int dll01Func00();
#if defined(__cplusplus)
extern "C" {
#endif
DLL00_EXPORT_API int dll00Func00();
#if defined(__cplusplus)
}
#endif
int dll00Func00() {
printf("%s - %d - %s\n", __FILE__, __LINE__, __FUNCTION__);
dll01Func00();
return 0;
}
dll01.c:
#include <stdio.h>
#if defined(_WIN32)
# define DLL01_EXPORT_API __declspec(dllexport)
#else
# define DLL01_EXPORT_API
#endif
#if defined(__cplusplus)
extern "C" {
#endif
DLL01_EXPORT_API int dll01Func00();
#if defined(__cplusplus)
}
#endif
int dll01Func00() {
printf("%s - %d - %s\n", __FILE__, __LINE__, __FUNCTION__);
return 0;
}
code00.py:
#!/usr/bin/env python
import argparse
import ctypes as cts
import os
import sys
DLL_NAME = "./dll00.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")
METH_ADDLLDIR = "a"
METH_PATH = "p"
METHS = (
METH_ADDLLDIR,
METH_PATH,
)
def parse_args(*argv):
parser = argparse.ArgumentParser(description="Python .dll search path (Win) example")
parser.add_argument("--path", "-p", choices=METHS)
parser.add_argument("--winmode", "-w", type=int)
args, unk = parser.parse_known_args()
if unk:
print("Warning: Ignoring unknown arguments: {:}".format(unk))
return args.path, args.winmode
def main(*argv):
meth, wmod = parse_args()
print("PATH (original): {:}\n".format(os.environ.get("PATH")))
print("Using winmode={:}".format(wmod))
if meth is not None:
subdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), "subdir00")
if meth == METH_ADDLLDIR:
add_dll_directory = getattr(os, "add_dll_directory", None)
if add_dll_directory:
os.add_dll_directory(subdir)
print("Using AddDllDirectory()\n")
elif meth == METH_PATH:
os.environ["PATH"] = os.pathsep.join((os.environ.get("PATH", ""), subdir))
print("Using %PATH%\n")
dll00 = cts.CDLL(DLL_NAME, winmode=wmod)
print("Dll: {:}".format(dll00))
if False: # No need to actually call the function
dll00Func00 = dll00.dll00Func00
dll00Func00.argtypes = ()
dll00Func00.restype = cts.c_int
res = dll00Func00()
print("\n{0:s} returned: {1:d}".format(dll00Func00.__name__, res))
if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.\n")
sys.exit(rc)
Notes:
There are 2 variables here (alterable via command line arguments):
path - how subdir00 should be added to .dll search paths:
Do nothing (don't add it)
Pass it to os.add_dll_directory
Append it to %PATH%
winmode - to be passed to CDLL initializer (only illustrating for 0 and None)
As a consequence, 6 combinations emerge
Output:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q059330863]> sopr.bat ### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ### [prompt]> "c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\VC\Auxiliary\Build\vcvarsall.bat" x64 > nul [prompt]> tree /a /f Folder PATH listing for volume SSD0-WORK Volume serial number is AE9E-72AC E:. | code00.py | dll00.c | dll01.c | test.bat | \---subdir00 [prompt]> :: Build .dlls [prompt]> cl /nologo /DDLL /MD dll01.c /link /NOLOGO /DLL /OUT:subdir00\dll01.dll dll01.c Creating library subdir00\dll01.lib and object subdir00\dll01.exp [prompt]> [prompt]> cl /nologo /DDLL /MD dll00.c /link /NOLOGO /DLL /OUT:dll00.dll subdir00\dll01.lib dll00.c Creating library dll00.lib and object dll00.exp [prompt]> [prompt]> tree /a /f Folder PATH listing for volume SSD0-WORK Volume serial number is AE9E-72AC E:. | code00.py | dll00.c | dll00.dll | dll00.exp | dll00.lib | dll00.obj | dll01.c | dll01.obj | test.bat | \---subdir00 dll01.dll dll01.exp dll01.lib [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" code00.py -h Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 usage: code00.py [-h] [--path {a,p}] [--winmode WINMODE] Python .dll search path (Win) example options: -h, --help show this help message and exit --path {a,p}, -p {a,p} --winmode WINMODE, -w WINMODE [prompt]> [prompt]> :: Going through combinations. When an argument is not passed, its default value is None [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" code00.py Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 PATH (original): c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\\Extensions\Microsoft\IntelliCode\CLI;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\VCPackages;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TestWindow;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\MSBuild\Current\bin\Roslyn;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\\x64;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4 .8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\devinit;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64;C:\Program Files (x86)\Windows Kits\10\bin\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\\MSBuild\Current\Bin;C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Install\pc064\Docker\Docker\Version\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\dotnet\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts;C:\Us ers\cfati\AppData\Local\Microsoft\WindowsApps;C:\Users\cfati\.dotnet\tools;;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\Linux\bin\ConnectionManagerExe Using winmode=None Traceback (most recent call last): File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 57, in <module> rc = main(*sys.argv[1:]) File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 44, in main dll00 = cts.CDLL(DLL_NAME, winmode=wmod) File "c:\Install\pc064\Python\Python\03.10\lib\ctypes\__init__.py", line 374, in __init__ self._handle = _dlopen(self._name, mode) FileNotFoundError: Could not find module 'e:\Work\Dev\StackOverflow\q059330863\dll00.dll' (or one of its dependencies). Try using the full path with constructor syntax. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" code00.py -w 0 Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 PATH (original): c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\\Extensions\Microsoft\IntelliCode\CLI;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\VCPackages;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TestWindow;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\MSBuild\Current\bin\Roslyn;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\\x64;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4 .8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\devinit;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64;C:\Program Files (x86)\Windows Kits\10\bin\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\\MSBuild\Current\Bin;C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Install\pc064\Docker\Docker\Version\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\dotnet\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts;C:\Us ers\cfati\AppData\Local\Microsoft\WindowsApps;C:\Users\cfati\.dotnet\tools;;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\Linux\bin\ConnectionManagerExe Using winmode=0 Traceback (most recent call last): File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 57, in <module> rc = main(*sys.argv[1:]) File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 44, in main dll00 = cts.CDLL(DLL_NAME, winmode=wmod) File "c:\Install\pc064\Python\Python\03.10\lib\ctypes\__init__.py", line 374, in __init__ self._handle = _dlopen(self._name, mode) FileNotFoundError: Could not find module './dll00.dll' (or one of its dependencies). Try using the full path with constructor syntax. [prompt]> [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" code00.py -p a Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 PATH (original): c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\\Extensions\Microsoft\IntelliCode\CLI;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\VCPackages;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TestWindow;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\MSBuild\Current\bin\Roslyn;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\\x64;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4 .8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\devinit;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64;C:\Program Files (x86)\Windows Kits\10\bin\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\\MSBuild\Current\Bin;C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Install\pc064\Docker\Docker\Version\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\dotnet\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts;C:\Us ers\cfati\AppData\Local\Microsoft\WindowsApps;C:\Users\cfati\.dotnet\tools;;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\Linux\bin\ConnectionManagerExe Using winmode=None Using AddDllDirectory() Dll: <CDLL 'e:\Work\Dev\StackOverflow\q059330863\dll00.dll', handle 7ffe6aaf0000 at 0x1f896d9ffd0> Done. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" code00.py -p a -w 0 Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 PATH (original): c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\\Extensions\Microsoft\IntelliCode\CLI;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\VCPackages;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TestWindow;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\MSBuild\Current\bin\Roslyn;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\\x64;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4 .8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\devinit;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64;C:\Program Files (x86)\Windows Kits\10\bin\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\\MSBuild\Current\Bin;C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Install\pc064\Docker\Docker\Version\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\dotnet\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts;C:\Us ers\cfati\AppData\Local\Microsoft\WindowsApps;C:\Users\cfati\.dotnet\tools;;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\Linux\bin\ConnectionManagerExe Using winmode=0 Using AddDllDirectory() Traceback (most recent call last): File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 57, in <module> rc = main(*sys.argv[1:]) File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 44, in main dll00 = cts.CDLL(DLL_NAME, winmode=wmod) File "c:\Install\pc064\Python\Python\03.10\lib\ctypes\__init__.py", line 374, in __init__ self._handle = _dlopen(self._name, mode) FileNotFoundError: Could not find module './dll00.dll' (or one of its dependencies). Try using the full path with constructor syntax. [prompt]> [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" code00.py -p p Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 PATH (original): c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\\Extensions\Microsoft\IntelliCode\CLI;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\VCPackages;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TestWindow;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\MSBuild\Current\bin\Roslyn;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\\x64;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4 .8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\devinit;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64;C:\Program Files (x86)\Windows Kits\10\bin\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\\MSBuild\Current\Bin;C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Install\pc064\Docker\Docker\Version\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\dotnet\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts;C:\Us ers\cfati\AppData\Local\Microsoft\WindowsApps;C:\Users\cfati\.dotnet\tools;;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\Linux\bin\ConnectionManagerExe Using winmode=None Using %PATH% Traceback (most recent call last): File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 57, in <module> rc = main(*sys.argv[1:]) File "e:\Work\Dev\StackOverflow\q059330863\code00.py", line 44, in main dll00 = cts.CDLL(DLL_NAME, winmode=wmod) File "c:\Install\pc064\Python\Python\03.10\lib\ctypes\__init__.py", line 374, in __init__ self._handle = _dlopen(self._name, mode) FileNotFoundError: Could not find module 'e:\Work\Dev\StackOverflow\q059330863\dll00.dll' (or one of its dependencies). Try using the full path with constructor syntax. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" code00.py -p p -w 0 Python 3.10.9 (tags/v3.10.9:1dd9be6, Dec 6 2022, 20:01:21) [MSC v.1934 64 bit (AMD64)] 064bit on win32 PATH (original): c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\\Extensions\Microsoft\IntelliCode\CLI;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\VCPackages;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TestWindow;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\MSBuild\Current\bin\Roslyn;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\\x64;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\vs2019\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4 .8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\devinit;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64;C:\Program Files (x86)\Windows Kits\10\bin\x64;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\\MSBuild\Current\Bin;C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\Tools\;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Install\pc064\Docker\Docker\Version\Docker\resources\bin;C:\ProgramData\DockerDesktop\version-bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\dotnet\;C:\Users\cfati\AppData\Local\Programs\Python\Launcher\;e:\Work\Dev\Utils\current\Win;e:\Work\Dev\VEnvs\py_pc064_03.09_test0\Scripts;C:\Us ers\cfati\AppData\Local\Microsoft\WindowsApps;C:\Users\cfati\.dotnet\tools;;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;c:\Install\pc032\Microsoft\VisualStudioCommunity\2019\Common7\IDE\VC\Linux\bin\ConnectionManagerExe Using winmode=0 Using %PATH% Dll: <CDLL './dll00.dll', handle 7ffe6aaf0000 at 0x142a7a73cd0> Done.
Only 2 combinations (as expected) were successful (use subdir00):
Pass it to os.add_dll_directory (with winmode None)
Add it to %PATH% (with winmode 0)
There are more ways of adding dirs where to search for (dependent) .dlls:
os.add_dll_directory:
Default (and recommended) option (there are 3rd-party modules that load .dlls this way)
Consistent with the way Python loads extension module (.pyd) dependencies
%PATH% (and alter winmode):
Works with older (< v3.8) Python versions
Seems closer with Nix - where paths are typically added to ${LD_LIBRARY_PATH} (DYLD_LIBRARY_PATH, LIBPATH, SHLIB_PATH, ...)
Can be customized by winmode's value
Change directory to .dll location (more like a workaround):
Related (more or less):
[SO]: Load a DLL with dependencies in Python (@CristiFati's answer)
[SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer)
[SO]: Discover missing module using command-line ("DLL load failed" error) (@CristiFati's answer)
Upvotes: 29
Reputation: 1
Just "Visual C++ Redistributable Package per Visual Studio 2013". The problem will be solved.
Upvotes: -2
Reputation: 101
I partially agree with @MadPhysicist's answer, but I have Python 3.9, not 3.8, and with winmode=0
error haven't disappeared. But with winmode=1
everything is working!
Upvotes: 4
Reputation: 114310
A year late, but I've figured out what is going on and how to fix it. If you look at the code for ctypes.CDLL
on around line 340, you can see that the docs are actually incorrect. The code defines the constructor as
def __init__(self, name, mode=DEFAULT_MODE, handle=None,
use_errno=False, use_last_error=False, winmode=None):
The docs, however, say winmode=0
. If you look at line 358, you can see that it matters quite a bit. When winmode=None
, the search mode used by _ctypes.LoadLibrary
in line 374 (aliased as _dlopen
in line 110) is set to nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
on line 363. This search mode does not appear to respond to changes to os.environ['PATH']
, sys.path
or os.add_dll_directory
.
However, if you bypass that setting by using winmode=0
instead of None
, the library appears to load fine. Zero is a valid mode for a full path (as would be nt._LOAD_WITH_ALTERED_SEARCH_PATH
). A full list of modes is available here: https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa, under the dwFlags
parameter.
As @CristiFati indicates, the behavior changed in Python 3.8. This happened because prior to that, the winmode
parameter did not exist. Instead, mode
was used directly, with a default value of ctypes.DEFAULT_MODE
, which happens to correspond to a zero and work on all platforms.
Python bug report to resolve discrepancy: https://bugs.python.org/issue42114
Upvotes: 32
Reputation: 287
OK so i fixed it, it was required that i changed the working directory to where the script was being executed before loading the dll from the same place.
os.chdir('path_to_working_dlls_directoy')
not entirely sure why this helped though.
Upvotes: 2