Python Ctypes-加载dll引发OSError:[WinError 193]%1不是有效的Win32应用程序

问题描述 投票:0回答:1

我已经尝试运行一个python代码示例,该示例代码使用ctypes从库中获取函数。可以找到示例here。我按照说明进行,除了一个小的修改之外,我使用了完全相同的代码。我一直试图在Windows 10(64位),python 3.7(64位)上运行此命令,但收到此错误消息:

Traceback (most recent call last):
  File "C:/Users/gifr9302/PycharmProjects/testpytoc/myfunc.py", line 128, in <module>
    libmyfunc = npct.load_library('myfunc.dll', os.path.dirname(os.path.abspath(__file__)))
  File "C:\Users\gifr9302\AppData\Local\Programs\Python\Python37\lib\site-packages\numpy\ctypeslib.py", line 152, in load_library
    return ctypes.cdll[libpath]
  File "C:\Users\gifr9302\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 431, in __getitem__
    return getattr(self, name)
  File "C:\Users\gifr9302\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 426, in __getattr__
    dll = self._dlltype(name)
  File "C:\Users\gifr9302\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 356, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 n’est pas une application Win32 valide

翻译:

OSError: [WinError 193] %1 is not a valid Win32 application

我尝试创建dll而不是so文件,但仍然遇到相同的错误。似乎它试图在64位系统上运行32位应用程序,但我不确定为什么。谁能帮忙?

python c windows dll ctypes
1个回答
1
投票

以防万一。[Python 3.Docs]: ctypes - A foreign function library for Python提及(尽管与它没有太大关系)。>

它是([[[[ERROR_BAD_EXE_FORMAT

1930xC1)上的(Python)包装。在[MS.Docs]: System Error Codes (0-499)中检查它。1。错误错误消息令人困惑(特别是由于

%1

占位符)。有关更多详细信息,请检查[SO]: Why is %1 rarely substituted in “%1 is not a valid Win32 application.”[Win尝试加载它认为是可执行映像的文件时会发生此错误(。exe

。dll

,...),但实际上并非如此。遇到这种情况的情况多种多样(Google出现错误,将会产生很多结果)。[从文件加载图像时,有很多可能的原因(现有且可读,否则错误会有所不同-请看最后的项目符号之一:]已下载且下载不完整

由于文件系统问题而损坏

    被错误覆盖
  • 2个主要用例导致此错误:
  • 尝试运行不是

    。exe

    [SO]: OSError: [WinError 193] %1 is not a valid Win32 application)的文件
    1. 正在尝试在进程中加载​​
    2. 。dll
    3. (运行。exe)。这是我要重点关注的一个
  • 下面是一个示例,其中虚拟可执行文件尝试加载。dll。

    code0.c

    #include <stdio.h> #include <Windows.h> int main() { DWORD gle = 0; HMODULE hMod = LoadLibraryA(".\\dll0.dll"); if (hMod == NULL) { gle = GetLastError(); printf("LoadLibrary failed: %d (0x%08X)\n", gle, gle); } else { FreeLibrary(hMod); } return gle; }

    输出:

    Note

    :即使复制/粘贴代码片段分散在答案中,我仍将重用此
      cmd控制台

  • [cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q057187566]> sopr.bat *** Set shorter prompt to better fit when pasted in StackOverflow (or other) pages *** [prompt]> "c:\Install\x86\Microsoft\Visual Studio Community\2017\VC\Auxiliary\Build\vcvarsall.bat" x64 ********************************************************************** ** Visual Studio 2017 Developer Command Prompt v15.9.14 ** Copyright (c) 2017 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x64' [prompt]> dir /b code0.c dll0.c script0.py [prompt]> cl /nologo code0.c /link /NOLOGO /OUT:code0_064.exe code0.c [prompt]> :: Creating an invalid dll [prompt]> echo garbage> dll0.dll [prompt]> dir /b code0.c code0.obj code0_064.exe dll0.c dll0.dll script0.py [prompt]> code0_064.exe LoadLibrary failed: 193 (0x000000C1) 如图所示,我创建了一个文件
    dll0.dll
    ,其中包含文本“
    垃圾
    ”,因此它是一个内容无效的

    。dll

  • 文件。此错误最常见的情况是体系结构不匹配:

      [64bit进程试图加载
    • 32bit
    。dll
    32bit进程试图加载
  • 64bit
  • 。dll
    在以上两种情况中的任何一种情况下,即使。dll包含适用于其他体系结构的有效映像,对于当前进程PoV而言,该映像仍然无效。要运行

    OK

    涉及的2个CPU体系结构必须匹配 1 [12。 Python上下文

    ctypes

    在加载。dll时执行相同的操作:它在

    。dll

    名称上调用[MS.Docs]: LoadLibraryW function。因此,对于Python进程,这是完全相同的情况,其中ctypes尝试将。dll加载到其中。script0.py:#!/usr/bin/env python3 import sys import os import ctypes DLL_BASE_NAME = "dll0" def main(args): dll_name = os.path.join(os.path.abspath(os.path.dirname(__file__)), (args[0] if args else DLL_BASE_NAME) + ".dll") print("Attempting to load: [{0:s}]".format(dll_name)) dll0 = ctypes.CDLL(dll_name) func0 = dll0.dll0Func0 func0.restype = ctypes.c_int res = func0() print("{0:s} returned {1:d}".format(func0.__name__, res)) if __name__ == "__main__": print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform)) main(sys.argv[1:]) print("\nDone.")

    输出:

    [prompt]> :: dll0.dll still contains garbage [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" script0.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll0.dll] Traceback (most recent call last): File "script0.py", line 24, in <module> main(sys.argv[1:]) File "script0.py", line 14, in main dll0 = ctypes.CDLL(dll_name) File "c:\install\x64\python\python\03.07.03\Lib\ctypes\__init__.py", line 356, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application

    这里是

    1 [1

    (从上面)的一个示例,它将尝试所有4种组合。dll0.c

    #include <inttypes.h> #if defined(_WIN32) # define DLL0_EXPORT_API __declspec(dllexport) #else # define DLL0_EXPORT_API #endif DLL0_EXPORT_API size_t dll0Func0() { return sizeof(void*); }

    输出:

    [prompt]> :: Still building for 64bit from previous vcvarsall call [prompt]> [prompt]> cl /nologo /DDLL dll0.c /link /NOLOGO /DLL /OUT:dll0_064.dll dll0.c Creating library dll0_064.lib and object dll0_064.exp [prompt]> [prompt]> "c:\Install\x86\Microsoft\Visual Studio Community\2017\VC\Auxiliary\Build\vcvarsall.bat" x86 ********************************************************************** ** Visual Studio 2017 Developer Command Prompt v15.9.14 ** Copyright (c) 2017 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x86' [prompt]> cl /nologo /DDLL dll0.c /link /NOLOGO /DLL /OUT:dll0_032.dll dll0.c Creating library dll0_032.lib and object dll0_032.exp [prompt]> dir /b *.dll dll0.dll dll0_032.dll dll0_064.dll [prompt]> [prompt]> :: Python 64bit [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" script0.py dll0_064 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll0_064.dll] dll0Func0 returned 8 Done. [prompt]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" script0.py dll0_032 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll0_032.dll] Traceback (most recent call last): File "script0.py", line 24, in <module> main(sys.argv[1:]) File "script0.py", line 14, in main dll0 = ctypes.CDLL(dll_name) File "c:\install\x64\python\python\03.07.03\Lib\ctypes\__init__.py", line 356, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application [prompt]> [prompt]> :: Python 32bit [prompt]> "e:\Work\Dev\VEnvs\py_032_03.07.03_test0\Scripts\python.exe" script0.py dll0_032 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)] 32bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll0_032.dll] dll0Func0 returned 4 Done. [prompt]> "e:\Work\Dev\VEnvs\py_032_03.07.03_test0\Scripts\python.exe" script0.py dll0_064 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)] 32bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll0_064.dll] Traceback (most recent call last): File "script0.py", line 24, in <module> main(sys.argv[1:]) File "script0.py", line 14, in main dll0 = ctypes.CDLL(dll_name) File "c:\install\x86\python\python\03.07.03\Lib\ctypes\__init__.py", line 356, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application

    3。奖金
    在以上示例中,通过显式调用
    LoadLibrary(或

    LoadLibraryEx

    )“按需”加载了[[.dll

    。另一种情况是当

    。exe

    。dll依赖(链接到)另一个。dll,并且它自动加载时它正在被加载(尽管我几乎可以肯定LoadLibrary-或更低级别的函数-在相关的[[.dll上自动被调用)。在下面的示例中,dll0 * .dll取决于dll1 * .dll。仅举例说明32bit(因为这是由先前操作设置的当前构建环境)。dll1.h:#if defined(_WIN32) # if defined(DLL1_EXPORTS) # define DLL1_EXPORT_API __declspec(dllexport) # else # define DLL1_EXPORT_API __declspec(dllimport) # endif #else # define DLL1_EXPORT_API #endif DLL1_EXPORT_API void dll1Func0(); dll1.c:

    #include <stdio.h> #define DLL1_EXPORTS #include "dll1.h" void dll1Func0() { printf("In [%s]\n", __FUNCTION__); }

    dll0.c
    (已修改):

    #include <inttypes.h> #if defined(_WIN32) # define DLL0_EXPORT_API __declspec(dllexport) #else # define DLL0_EXPORT_API #endif #include "dll1.h" DLL0_EXPORT_API size_t dll0Func0() { dll1Func0(); return sizeof(void*); }

    输出

    [prompt]> :: Still building for 32bit from previous vcvarsall call [prompt]> [prompt]> cl /nologo /DDLL dll1.c /link /NOLOGO /DLL /OUT:dll1_032.dll dll1.c Creating library dll1_032.lib and object dll1_032.exp [prompt]> cl /nologo /DDLL dll0.c /link /NOLOGO /DLL /OUT:dll0_032.dll dll0.c Creating library dll0_032.lib and object dll0_032.exp dll0.obj : error LNK2019: unresolved external symbol __imp__dll1Func0 referenced in function _dll0Func0 dll0_032.dll : fatal error LNK1120: 1 unresolved externals [prompt]> [prompt]> cl /nologo /DDLL dll0.c /link /NOLOGO /DLL /OUT:dll0_032.dll dll1_032.lib dll0.c Creating library dll0_032.lib and object dll0_032.exp [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_032_03.07.03_test0\Scripts\python.exe" script0.py dll0_032 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)] 32bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll0_032.dll] In [dll1Func0] dll0Func0 returned 4 Done. [prompt]> :: Messing up dll1_032.dll [prompt]> echo garbage> dll1_032.dll [prompt]> "e:\Work\Dev\VEnvs\py_032_03.07.03_test0\Scripts\python.exe" script0.py dll0_032 Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 21:26:53) [MSC v.1916 32 bit (Intel)] 32bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll0_032.dll] Traceback (most recent call last): File "script0.py", line 24, in <module> main(sys.argv[1:]) File "script0.py", line 14, in main dll0 = ctypes.CDLL(dll_name) File "c:\install\x86\python\python\03.07.03\Lib\ctypes\__init__.py", line 356, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application

    陈述明显的事实:如果我不是将垃圾数据写入dll1_032.dll,而是为

    64bit
    构建它,但会选择相同的错误,因为它变短了。 >
    4。结论

    我在下一个项目符号中声明的所有内容,也适用于其后的项目。

    在示例中,上面的错误是由于正在加载的。dll或其直接依赖项之一(间接级别1)中发生损坏。不难发现,多次应用同一原理,行为不会改变,因此对于任何级别的间接调用都是有效的。想象一个

    。dll依赖于其他几个

    。dll

    ,而每个依次依赖于其他几个,依此类推...。这称为
      依赖关系树
    。因此,无论
  • 在树中的哪个位置都会发生此错误,它都会传播到根节点
  • 依赖关系树传播也适用于其他错误。 广泛遇到的另一个是ERROR_MOD_NOT_FOUND126
  • 0x7E)。这意味着未找到具有指定名称的。dll
  • 讨论的所有内容同样适用:如果。dll是正在导入的扩展模块(。pyd),则>]
  • 如果由于导入了另一个模块而正在加载
      。dll
  • ,则>
  • 讨论的所有内容也适用于Nix系统,错误(和相应的消息)明显不同
  • © www.soinside.com 2019 - 2024. All rights reserved.