【问题标题】:Ctypes: cannot import windllCtypes:无法导入windll
【发布时间】:2016-03-06 12:57:15
【问题描述】:

我在 Windows 7 64 位上运行 Python 2.7 32 位 (Anaconda)。

我想用ctypes来做win32 API调用,我有一个很奇怪的问题:我可以import ctypes,但不能import ctypes.windll,我得到以下错误:

ImportError: No module named windll

我已经抓取了网络,但我没有发现任何与我的问题相似的东西(这可能是根本无法导入 ctypes,或者是您尝试导入的 DLL 中的错误)。

有人知道我做错了什么吗?

【问题讨论】:

    标签: python ctypes


    【解决方案1】:

    看来您不能只使用import ctypes.windll,您需要import ctypes,然后使用ctypes.windll。我通过打印 ctypes 的所有属性发现了这一点:

    import ctypes
    print dir(ctypes)
    

    有趣的是,IPython 自动补全在这里具有误导性,因为在 import ctypes. 之后自动补全时,它没有将 windll 显示为可能的选择。

    【讨论】:

    • 请记住,使用 ctypes.windll 会让您受到任何碰巧加载相同 DLL 并将原型(restypeargtypeserrcheck)设置在您也在调用的函数。函数指针实例缓存在WinDLL 实例上,该实例缓存在windll 上,因此与其他用户定义的类型和errcheck 函数的定义方式相比,您可能会遇到冲突。从长远来看,您最好调用ctypes.WinDLL 来获取特定于您的模块或脚本的实例。
    • @eryksun 非常感谢您的提示!
    • 要反弹 eryksun 的评论:您不能直接调用 ctypes.WinDLL.kernel32,您需要执行以下操作:from ctypes import LibraryLoader; windll = LibraryLoader(ctypes.WinDLL),然后您可以调用 windll.kernel32,而不会出现 eryksun 提到的重新定义问题。
    • 你不要打电话给windll.kernel32。你得到一个函数指针实例作为属性,例如windll.kernel32.CreateFileW。使用加载器的另一个问题是它不允许您传递参数use_last_error=True,它与ctypes.get_last_error()ctypes.set_last_error() 一起使用。我建议你使用kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
    • 然后,当 MSDN 上记录的用于设置最后一个错误值的函数失败时,您可以使用 raise ctypes.WinError(ctypes.get_last_error()) 获得格式良好的异常。
    猜你喜欢
    • 2020-04-07
    • 2020-03-30
    • 2019-12-11
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    相关资源
    最近更新 更多