У меня есть следующий код, который я запускаю:
def PATH():
return "\n"+"\n".join(os.environ["PATH"].split(os.pathsep))
def syspath():
return "\n"+"\n".join(sys.path)
def test_haha():
logger.info(f"CWD: {os.getcwd()}")
logger.info(f"sys.path: {syspath()}")
logger.info(f"PATH: {PATH()}")
logger.info(f"Found? {str(util.find_library('PCANBasic'))}")
windll.LoadLibrary("PCANBasic")
# pcanbasic_path = str(Path(os.getcwd()) / "PCANBasic.dll")
И мой PCANBasic.dll
находится в моем рабочем каталоге. Я использую windows 10.
Если я запускаю python из командной строки, все работает правильно.
Однако у меня есть IDE, написанная на pyqt и связанная с PyInstaller. Эта IDE имеет функцию для запуска файла Python (вызывая QProcess в пакетном файле, который запускает ту же команду, которую я запускаю вручную), и в этом случае происходит сбой со следующим:
def test_haha():
logger.info(f"CWD: {os.getcwd()}")
logger.info(f"sys.path: {syspath()}")
logger.info(f"PATH: {PATH()}")
logger.info(f"Found? {str(util.find_library('PCANBasic'))}")
> windll.LoadLibrary("PCANBasic")
demo_test\test_dll.py:23:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Users\myuser\python3_portable\lib\ctypes\__init__.py:434: in LoadLibrary
return self._dlltype(name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <WinDLL 'PCANBasic', handle 0 at 0x1e9e6480668>, name = 'PCANBasic'
mode = 0, handle = None, use_errno = False, use_last_error = False
def __init__(self, name, mode=DEFAULT_MODE, handle=None,
use_errno=False,
use_last_error=False):
self._name = name
flags = self._func_flags_
if use_errno:
flags |= _FUNCFLAG_USE_ERRNO
if use_last_error:
flags |= _FUNCFLAG_USE_LASTERROR
if _sys.platform.startswith("aix"):
"""When the name contains ".a(" and ends with ")",
e.g., "libFOO.a(libFOO.so)" - this is taken to be an
archive(member) syntax for dlopen(), and the mode is adjusted.
Otherwise, name is presented to dlopen() as a file argument.
"""
if name and name.endswith(")") and ".a(" in name:
mode |= ( _os.RTLD_MEMBER | _os.RTLD_NOW )
class _FuncPtr(_CFuncPtr):
_flags_ = flags
_restype_ = self._func_restype_
self._FuncPtr = _FuncPtr
if handle is None:
> self._handle = _dlopen(self._name, mode)
E OSError: [WinError 126] The specified module could not be found
CWD, sys.path
идентичны, а PATH
в основном одинаковы (версия IDE имеет папку bin PyQt5).
В итоге, вопросы:
1 - Что может быть причиной этой разницы в поведении, когда в одном случае я могу загрузить DLL из текущего рабочего каталога, а вВ другом случае я не?
2 - В любом случае, если DLL находится в любом каталоге в PATH, он работает. Может быть, это плохая практика - полагаться на dll в рабочем каталоге и вместо этого устанавливать их где-нибудь правильно?
Спасибо!