windows 无法在Python中导入dll模块

l5tcr1uw  于 2022-11-18  发布在  Windows
关注(0)|答案(6)|浏览(302)

几天来,我一直在紧张地试图在Windows上编译一个修改后的libuvc版本,现在我终于做到了,但似乎无法在Python上加载它。我已经编译了这个lib,并在Linux机器上使用相同版本的Python成功导入,它一点也不喜欢w10。

系统

  • 绕组10 64位
  • Python 3.8 64位
  • libusb文件1.022
  • 使用MinGW64编译的libuvc.dll
    问题

当尝试

import ctypes
import ctypes.util
name = ctypes.util.find_library('libuvc')
lib = ctypes.cdll.LoadLibrary(name)

出现以下错误:

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!

问题是文件在被util.find_library发现后就已经存在了,但是python并不认为它在那里,或者输出只是默认的。我在这里遗漏了什么呢?为什么不仅不能加载模块,还不能找到它呢?很抱歉,我没有比这更多的输出了。
我试过用不同的方式重新格式化字符串,但是消息没有改变。

ruoxqz4g

ruoxqz4g1#

Python 3.8开始,.dll 搜索机制已更改(*特定于Win)。
根据【Python.Docs】:添加dll目录(路径)(强调是我的):
将路径添加到DLL搜索路径。
当解析导入的扩展模块的依赖项(模块本身是通过sys.path解析的)以及ctypes时,会使用此搜索路径。
...

**上市时间: windows **。

因此,您可以:

os.add_dll_directory("${path_to_working_dlls_directoy}")

其中,${path_to_working_dlls_directoy} 是实际路径的占位符,(显然)应该替换为实际路径。
您可以检查[SO]: PyWin32 and Python 3.8.0 (@CristiFati's answer)(虽然看起来非常不同,但原因相同)以了解更多详细信息。

  • P.S.*:*Nix**操作系统 * 不受影响。
jtoj6r0c

jtoj6r0c2#

晚了一年,但是我已经弄清楚了发生了什么,以及如何修复它。如果您查看第340行左右的ctypes.CDLL代码,您可以看到文档实际上是不正确的。代码将构造函数定义为

def __init__(self, name, mode=DEFAULT_MODE, handle=None,
             use_errno=False, use_last_error=False, winmode=None):

但是,文档中说的是winmode=0。如果您查看第358行,您会发现它非常重要。当winmode=None,即第374行中_ctypes.LoadLibrary使用的搜索模式(在第110行中别名为_dlopen)在第363行上设置为nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS。此搜索模式似乎不响应对os.environ['PATH']sys.pathos.add_dll_directory的更改。
但是,如果您使用winmode=0而不是None来绕过该设置,则库看起来可以正常加载。零是完整路径的有效模式(如nt._LOAD_WITH_ALTERED_SEARCH_PATH)。以下是模式的完整列表:dwFlags参数下的https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa
正如@CristiFati所指出的,在Python 3.8中,行为发生了变化,这是因为在此之前,winmode参数并不存在,而是直接使用mode,默认值为ctypes.DEFAULT_MODE,恰好对应于零,并且在所有平台上都有效。
用于解决差异的Python错误报告:https://bugs.python.org/issue42114

nnsrf1az

nnsrf1az3#

好的,所以我修复了它,它要求我改变工作目录的脚本正在执行之前,加载dll从同一个地方。

os.chdir('path_to_working_dlls_directoy')

不完全确定为什么这有帮助。

5n0oy7gb

5n0oy7gb4#

我部分同意@MadPhysicist的回答,但是我有Python 3.9,而不是3.8,并且winmode=0的错误还没有消失。但是winmode=1的一切都在工作!

rvpgvaaj

rvpgvaaj5#

只需“Visual C++可再发行软件包per Visual Studio 2013”。问题就会解决。

2skhul33

2skhul336#

您可以指定库的路径

import snap7
import struct
from snap7.common import Snap7Library
from snap7.util import *

# If you are using a different location for the library
Snap7Library(lib_location='C:/snap7/snap7.dll')
load_library() #Testing library is correctly <WinDLL 'C:\snap7\snap7.dll', handle 7ff9d5d90000 at 0x1a5a0417640>

plc = snap7.client.Client()
plc.connect("10.112.115.10",0,1)

相关问题