Python Ctypes抛出“;WindowsError:[错误193]%1不是有效的Win32应用程序;,但是它';这不是32/64位的问题
我在Ctypes中加载Windows DLL时遇到问题,这会引发错误:Python Ctypes抛出“;WindowsError:[错误193]%1不是有效的Win32应用程序;,但是它';这不是32/64位的问题,python,c++,visual-studio-2012,dll,ctypes,Python,C++,Visual Studio 2012,Dll,Ctypes,我在Ctypes中加载Windows DLL时遇到问题,这会引发错误: WindowsError: [Error 193] %1 is not a valid Win32 application 在我的例子中,它是一个32位DLL,在Windows 7 64位上使用VS2012构建,在我的开发机器上,我可以很好地加载它。我使用dumpbin/headers检查它是否为32位: FILE HEADER VALUES 14C machine (x86) 当我试图通过生产虚拟机(
WindowsError: [Error 193] %1 is not a valid Win32 application
在我的例子中,它是一个32位DLL,在Windows 7 64位上使用VS2012构建,在我的开发机器上,我可以很好地加载它。我使用dumpbin/headers
检查它是否为32位:
FILE HEADER VALUES
14C machine (x86)
当我试图通过生产虚拟机(也是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
从其他问题来看,我已经尝试了好几种方法
- ,问题表明我的环境必须是相同的,即32位Python,32位DLL。在我的开发系统和我正在测试的虚拟机上就是这样。在这两个方面,我都使用32位最新版本的WinPython。它在dev机器上工作,在VM上失败
- ,它与g++有关,并且依赖于旧的Visual Studio运行时。我用VS2012编译了所有内容,所以我认为这在这里不适用。在需要
的第三方库上有一个延迟加载的依赖项,但它被延迟加载并且从未被调用MSVCR80.dll
- 建议DLL需要导出一个C接口,确实如此
- 我知道DLL的文件路径/文件名是正确的,与以前一样,存在缺少DLL依赖项的问题,在那里我得到了一个Windows弹出窗口。这些都不见了
cdb
或windbg
。在调用CDLL(dllabspath)
之前调用windl.kernel32.DebugBreak()。在kernelbase上设置断点!加载库EXW
并通过g
恢复线程。当它重新进入调试器时,输入pt
执行函数return。然后输入!teb
检查螺纹的LastStatusValue
。此NT状态值可能更有帮助
进一步:
如果希望尽可能保持系统干净,请尝试以下操作:windell.kernelbase.LoadLibraryExW(c_wchar_p(dllabspath),None,0);status=windell.ntdll.RtlGetLastNtStatus()。
否则需要从SDK安装调试工具。通过设置环境变量\u NT\u symbol\u PATH=symsrv*symsrv.dll*C:\Symbols,可以根据需要从Microsoft的符号服务器下载符号*http://msdl.microsoft.com/download/symbols
,它将符号缓存在C:\symbols
调试时,这可能有助于:
有几个状态代码会产生Win32 errorerror\u BAD\u EXE\u FORMAT
(193)。在您的情况下,它是STATUS\u INVALID\u IMAGE\u FORMAT
(0xc00007b
)。可能在生产虚拟机中,它尝试加载的一个依赖DLL是64位的。在断点处,输入du poi(@esp+4)
打印第一个参数,这是它试图加载的DLL的unicode路径。还可以通过kc
检查堆栈跟踪
使用此提示,我在64位WinPCAP DLL上找到了一个依赖项。使用DependencyWalker查看所有内容时,两台机器上看起来都一样,都是64位的依赖关系,但显然在新机器上,DLL加载路径不同,它永远找不到32位版本。消息有时意味着文件名错了,例如,指定了一个目录名而不是DLL的完整路径。请在cdb或windbg等调试器下运行。在调用CDLL(dllabspath)
之前调用windl.kernel32.DebugBreak()。在kernelbase上设置断点!加载库EXW
并通过g
恢复线程。当它重新进入调试器时,输入pt
执行函数return。然后输入!teb
检查螺纹的LastStatusValue
。此NT状态值可能更有帮助。@cdarke:文件名100%正确。以前,使用相同的代码,我得到了缺少依赖DLL的弹出错误。如果您希望保持系统尽可能干净,请尝试以下操作:windl.kernelbase.LoadLibraryExW(c_wchar_p(dllabspath),None,0);status=windell.ntdll.RtlGetLastNtStatus()
。否则需要从SDK安装调试工具。通过设置环境变量\u NT\u symbol\u PATH=symsrv*symsrv.dll*C:\Symbols,可以根据需要从Microsoft的符号服务器下载符号*http://msdl.microsoft.com/download/symbols
,它将符号缓存在C:\symbols
中。