我在Ctypes中加载Windows DLL时遇到问题,这会引发错误:
WindowsError: [Error 193] %1 is not a valid Win32 application
就我而言,它是在Windows 7 64位上使用VS2012构建的32位DLL,在我的开发机器上我可以加载它。我使用dumpbin /headers
检查它是32位:
FILE HEADER VALUES
14C machine (x86)
当我尝试在生产VM(也是Windows 7 64位)上通过Ctypes加载相同的DLL时,会出现此问题。我在做的是:
from ctypes import *
self.dll = CDLL(dllabspath)
我明白了:
File "C:\Users\user\Desktop\WinPython-32bit-2.7.10.1\.....\__init__.py", line 365, in __init__
self._handle = _dlopen(self._name, mode)
WindowsError: [Error 193] %1 is not a valid Win32 application
从其他问题我已经尝试了几件事。
MSVCR80.dll
的第三方库有一个延迟加载的依赖,但它是延迟加载的,从未调用过。该错误非常通用,相当神秘。既然它在同一个Python环境中的dev机器上运行,我假设它与一些Visual Studio安装可以给我的依赖关系有关吗?
我该如何正确排除故障?
@eryksun评论道:
在
cdb
或windbg
等调试器下运行。在致电windll.kernel32.DebugBreak()
之前打电话给CDLL(dllabspath)
。在kernelbase!LoadLibraryExW
上设置断点并通过g
恢复线程。当它重新进入调试器时,输入pt
以执行函数返回。然后输入!teb
以检查线程的LastStatusValue
。此NT状态值可能更有帮助。
进一步:
如果您希望尽可能保持系统清洁,请尝试以下方法:
windll.kernelbase.LoadLibraryExW(c_wchar_p(dllabspath), None, 0); status = windll.ntdll.RtlGetLastNtStatus().
否则,它需要从SDK安装调试工具。可以通过设置环境变量
_NT_SYMBOL_PATH=symsrv*symsrv.dll*C:\Symbols*http://msdl.microsoft.com/download/symbols
按需从Microsoft的符号服务器下载符号,C:\Symbols
缓存ERROR_BAD_EXE_FORMAT
中的符号
调试时,这可能会有所帮助:
有几个状态代码产生Win32错误
STATUS_INVALID_IMAGE_FORMAT
(193)。在你的情况下,它是0xC000007B
(du poi(@esp+4)
)。可能在生产VM中,它尝试加载的依赖DLL之一是64位。在断点处输入kc
以打印第一个参数,这是它试图加载的DLL的unicode路径。还可以通过qazxswpoi检查堆栈跟踪。
使用此提示,我发现了对64位WinPCAP DLL的依赖。使用DependencyWalker查看所有内容,它在两台机器上看起来都一样,抱怨64位依赖,但显然在新机器上,DLL加载路径不同,它永远找不到32位版本。