几天来我一直在努力尝试在Windows上编译libuvc的修改版本,而现在我终于做到了,我似乎无法在Python上加载它。我已经在Linux机器上使用相同版本的Python编译并成功导入了这个lib,根本不喜欢w10。
系统
问题
尝试
时[1,2]
我收到以下错误:
import ctypes
import ctypes.util
name = ctypes.util.find_library('libuvc')
lib = ctypes.cdll.LoadLibrary(name)
问题在于该文件存在,因为它是由util.find_library找到的,但是python认为它不存在,或者输出只是默认的。我在这里想念什么?有什么可能无法不仅加载模块而是找到模块?抱歉,我没有比这更多的输出了。
P.S:我尝试用不同的方式重新格式化字符串,但是消息没有改变。
答案 0 :(得分:2)
晚了一年,但我已经弄清楚了发生了什么以及如何解决它。如果您在ctypes.CDLL
附近查看line 340的代码,您会发现文档实际上是不正确的。代码将构造函数定义为
def __init__(self, name, mode=DEFAULT_MODE, handle=None,
use_errno=False, use_last_error=False, winmode=None):
然而,文档说winmode=0
。如果您查看line 358,就会发现它很重要。当winmode=None
时,{{3}中line 374中_ctypes.LoadLibrary
使用的搜索模式(在line 110中别名为_dlopen
)在{{3 }}。此搜索模式似乎不响应对line 363,os.environ['PATH']
或sys.path
的更改。
但是,如果通过使用nt._LOAD_LIBRARY_SEARCH_DEFAULT_DIRS
而不是winmode=0
绕过该设置,则库似乎可以正常加载。零是完整路径的有效模式(就像None
)。模式的完整列表位于此处:nt._LOAD_WITH_ALTERED_SEARCH_PATH
参数下的os.add_dll_directory
。
如https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexa所示,该行为在Python 3.8中已更改。发生这种情况是因为在此之前,dwFlags
参数不存在。而是直接使用winmode
,其默认值为mode
,该默认值恰好对应于零,并且可以在所有平台上使用。
Python错误报告以解决差异:@CristiFati
答案 1 :(得分:1)
好,所以我修复了它,要求我在从同一位置加载dll之前将工作目录更改为执行脚本的位置。
str(func_regex(xml))
# 'data.frame': 3 obs. of 13 variables:
# $ Id : Factor w/ 3 levels "4","5","6": 1 2 3
# $ Attrib1 : Factor w/ 3 levels "1","2","3": 1 2 3
# $ Attrib2 : Factor w/ 3 levels "7","8","9": 1 2 3
# $ Attrib3 : Factor w/ 2 levels "2008-07-31T21:42:52.667",..: 1 2 2
# $ Attrib4 : Factor w/ 3 levels "348","645","649": 2 3 1
# $ Attrib5 : Factor w/ 3 levels "2732","45103",..: 2 3 1
# $ Attrib8 : Factor w/ 2 levels "11652943","34873": 1 1 2
# $ Attrib10: Factor w/ 1 level "2019-09-03T17:25:25.207": 1 1 1
# $ Attrib11: Factor w/ 1 level "2019-10-21T14:03:54.607": 1 1 1
# $ Attrib13: Factor w/ 1 level "a|b|c|d|e|f|g": 1 1 1
# $ Attrib14: Factor w/ 2 levels "13","342": 1 2 2
# $ Attrib15: Factor w/ 2 levels "3","43": 1 2 2
# $ Attrib16: Factor w/ 2 levels "49","767": 1 2 2
str(func_xml2(xml))
# 'data.frame': 3 obs. of 18 variables:
# $ Id : Factor w/ 3 levels "4","5","6": 1 2 3
# $ Attrib1 : Factor w/ 3 levels "1","2","3": 1 2 3
# $ Attrib2 : Factor w/ 3 levels "7","8","9": 1 2 3
# $ Attrib3 : Factor w/ 2 levels "2008-07-31T21:42:52.667",..: 1 2 2
# $ Attrib4 : Factor w/ 3 levels "348","645","649": 2 3 1
# $ Attrib5 : Factor w/ 3 levels "2732","45103",..: 2 3 1
# $ Attrib6 : Factor w/ 2 levels "djhfbsdjhfbijhsdbfjkdbnfkjndaskjfnskjdlnfkjlsdnf",..: 2 2 1
# $ Attrib7 : Factor w/ 2 levels "8","9": 1 1 2
# $ Attrib8 : Factor w/ 2 levels "11652943","34873": 1 1 2
# $ Attrib9 : Factor w/ 2 levels "FHDHsf","Rich B": 2 2 1
# $ Attrib10: Factor w/ 1 level "2019-09-03T17:25:25.207": 1 1 1
# $ Attrib11: Factor w/ 1 level "2019-10-21T14:03:54.607": 1 1 1
# $ Attrib12: Factor w/ 3 levels "1","2","3": 1 2 3
# $ Attrib13: Factor w/ 1 level "a|b|c|d|e|f|g": 1 1 1
# $ Attrib14: Factor w/ 2 levels "13","342": 1 2 2
# $ Attrib15: Factor w/ 2 levels "3","43": 1 2 2
# $ Attrib16: Factor w/ 2 levels "49","767": 1 2 2
# $ Attrib17: Factor w/ 2 levels "2012-10-31T16:42:47.213",..: 1 1 2
不确定为什么这样做有帮助。
答案 2 :(得分:1)
从 Python 3.8 开始, .dll 搜索机制已更改。
根据[Python 3.Docs]: os.add_dll_directory(path)(强调是我的):
将路径添加到DLL搜索路径。
在解析导入的扩展模块的依赖项(模块本身通过sys.path解析),以及ctypes 时使用此搜索路径。
因此,您可以这样做:
os.add_dll_directory("path_to_working_dlls_directoy")
您可以检查[SO]: PyWin32 and Python 3.8.0 (@CristiFati's answer)(原因相同),以了解更多详细信息。
答案 3 :(得分:-1)
您可以指定库的路径
Private Sub DisplayTimeRemaining()
Label1.Text = CountdownTimer1.Remaining.ToString("hh\:mm\:ss")
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If CountdownTimer1.Enabled Then
CountdownTimer1.Stop()
CountdownTimer1.Reset()
Button1.Text = "Start"
Else
Button1.Text = "Stop"
CountdownTimer1.Reset()
CountdownTimer1.Period = TimeSpan.FromMinutes(NumericUpDown1.Value * 5)
CountdownTimer1.Start()
End If
DisplayTimeRemaining()
End Sub
Private Sub CountdownTimer1_Tick(sender As Object, e As EventArgs) Handles CountdownTimer1.Tick
DisplayTimeRemaining()
End Sub
Private Sub CountdownTimer1_Expired(sender As Object, e As EventArgs) Handles CountdownTimer1.Expired
Label1.Text = "Finished"
Button1.Text = "Start"
End Sub