I have tried to run an exemple of a python code that gets a function from a library using ctypes. The exemple can be found here. I followed the instruction and beside one minor modification, I have used the exact same code. I have been trying to run this on Windows 10 (64-bit), python 3.7 (64-bit) but got this error message:
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
translated:
OSError: [WinError 193] %1 is not a valid Win32 application
I have tried to create a dll instead of a so file and still got the same error. It would seem it tries to run a 32-bit application on a 64-bit system but I'm not sure why. Can anyone help?
Mentioning [Python.Docs]: ctypes - A foreign function library for Python (although this doesn't have very much to do with it) just in case.
The underlying error is ERROR_BAD_EXE_FORMAT (193, 0xC1). Check it in [MS.Docs]: System Error Codes (0-499). It's a general Win error (not related to Python). In the current case (related to Python), the exception is a (Python) wrapper over it.
The error message is confusing (especially because of %1 placeholder). For more details on that, check [SO]: Why is %1 rarely substituted in “%1 is not a valid Win32 application.”.
This error occurs when Win tries to load what it thinks it's an executable (PE) image (.exe, .dll, ...), but it actually isn't. There's a variety of situations when this is encountered (Googleing the error, would yield lots of results).
There are a bunch of possible reasons for this to happen when the image is loaded from a file (existing and readable, otherwise the error would differ - look at one of the bullets at the answer end):
2 main usecases lead to this error:
Below, it's an example of a dummy executable attempting to load a .dll.
main00.c:
#include <stdio.h>
#include <Windows.h>
int main()
{
DWORD gle = 0;
HMODULE hMod = LoadLibraryA(".\\dll00.dll");
if (hMod == NULL) {
gle = GetLastError();
printf("LoadLibrary failed: %d (0x%08X)\n", gle, gle);
} else {
FreeLibrary(hMod);
}
return gle;
}
Output:
[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]> :: Build for 064bit (pc064) [prompt]> "c:\Install\pc032\Microsoft\VisualStudioCommunity\2017\VC\Auxiliary\Build\vcvarsall.bat" x64 > nul [prompt]> dir /b code00.py dll00_v0.c main00.c [prompt]> cl /nologo main00.c /link /NOLOGO /OUT:main00_064.exe main00.c [prompt]> :: Creating an invalid .dll [prompt]> echo garbage> dll00.dll [prompt]> dir /b code00.py dll00.dll dll00_v0.c main00.c main00.obj main00_064.exe [prompt]> main00_064.exe LoadLibrary failed: 193 (0x000000C1)
As seen, I created a file dll00.dll containing the text "garbage", so it's a .dll file with invalid contents.
The most common case for this error, is an architecture mismatch:
In any of the above 2 cases, even if the .dll contains a valid image (for a different architecture), it's still invalid from the current process PoV. For things to run OK, the 2 involved CPU architectures must match (1).
CTypes does the same thing when loading a .dll: it calls [MS.Docs]: LoadLibraryW function on the .dll name.
So this is the exact same case for the Python process where CTypes tries to load the .dll in.
code00.py:
#!/usr/bin/env python3
import sys
import os
import ctypes as ct
DLL_BASE_NAME = "dll00"
def main(*argv):
dll_name = os.path.join(os.path.abspath(os.path.dirname(__file__)), (argv[0] if argv else DLL_BASE_NAME) + ".dll")
print("Attempting to load: [{0:s}]".format(dll_name))
dll00 = ct.CDLL(dll_name)
func00 = dll00.dll00Func00
func00.restype = ct.c_int
res = func00()
print("{0:s} returned {1:d}".format(func00.__name__, res))
if __name__ == "__main__":
print("Python {0:s} {1:03d}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))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)
Output:
[prompt]> :: dll00.dll still contains garbage [prompt]> [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.09_test0\Scripts\python.exe" code00.py Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] 064bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll00.dll] Traceback (most recent call last): File "code00.py", line 25, in <module> rc = main(*sys.argv[1:]) File "code00.py", line 14, in main dll00 = ct.CDLL(dll_name) File "c:\Install\pc064\Python\Python\03.07.09\lib\ctypes\__init__.py", line 364, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application
Here's an example for (#1) (from above), which attempts all 4 combinations.
dll00_v0.c:
#include <inttypes.h>
#if defined(_WIN32)
# define DLL00_EXPORT_API __declspec(dllexport)
#else
# define DLL00_EXPORT_API
#endif
DLL00_EXPORT_API size_t dll00Func00()
{
return sizeof(void*);
}
Output:
[prompt]> :: Still building for pc064 from previous vcvarsall call [prompt]> [prompt]> cl /nologo /DDLL dll00_v0.c /link /NOLOGO /DLL /OUT:dll00_064.dll dll00_v0.c Creating library dll00_064.lib and object dll00_064.exp [prompt]> [prompt]> :: Build for 032bit (pc032) [prompt]> "c:\Install\pc032\Microsoft\VisualStudioCommunity\2017\VC\Auxiliary\Build\vcvarsall.bat" x86 ********************************************************************** ** Visual Studio 2017 Developer Command Prompt v15.9.40 ** Copyright (c) 2017 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x86' [prompt]> cl /nologo /DDLL dll00_v0.c /link /NOLOGO /DLL /OUT:dll00_032.dll dll00_v0.c Creating library dll00_032.lib and object dll00_032.exp [prompt]> dir /b *.dll dll00.dll dll00_032.dll dll00_064.dll [prompt]> [prompt]> :: Python pc064 [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.09_test0\Scripts\python.exe" code00.py dll00_064 Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] 064bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll00_064.dll] dll00Func00 returned 8 Done. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc064_03.07.09_test0\Scripts\python.exe" code00.py dll00_032 Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:58:18) [MSC v.1900 64 bit (AMD64)] 064bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll00_032.dll] Traceback (most recent call last): File "code00.py", line 25, in <module> rc = main(*sys.argv[1:]) File "code00.py", line 14, in main dll00 = ct.CDLL(dll_name) File "c:\Install\pc064\Python\Python\03.07.09\lib\ctypes\__init__.py", line 364, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application [prompt]> [prompt]> :: Python pc032 [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc032_03.07.09_test0\Scripts\python.exe" code00.py dll00_032 Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:01:55) [MSC v.1900 32 bit (Intel)] 032bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll00_032.dll] dll00Func00 returned 4 Done. [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc032_03.07.09_test0\Scripts\python.exe" code00.py dll00_064 Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:01:55) [MSC v.1900 32 bit (Intel)] 032bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll00_064.dll] Traceback (most recent call last): File "code00.py", line 25, in <module> rc = main(*sys.argv[1:]) File "code00.py", line 14, in main dll00 = ct.CDLL(dll_name) File "c:\Install\pc032\Python\Python\03.07.09\lib\ctypes\__init__.py", line 364, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application
In the above examples, the .dll was loaded "on demand" by explicitly calling LoadLibrary (or LoadLibraryEx).
The other case is when a .exe or .dll depends on (was linked against) another .dll, and loads it automatically when itself is being loaded (although I'm almost certain that LoadLibrary - or maybe a lower level function - is automatically called under the hood on the dependent .dll).
In the example below, dll00*.dll depends on dll01*.dll.
Only exemplifying for 032bit (as this is the current build environment set by previous operation).
dll01.h:
#if defined(_WIN32)
# if defined(DLL01_EXPORTS)
# define DLL01_EXPORT_API __declspec(dllexport)
# else
# define DLL01_EXPORT_API __declspec(dllimport)
# endif
#else
# define DLL01_EXPORT_API
#endif
DLL01_EXPORT_API void dll01Func00();
dll01.c:
#include <stdio.h>
#define DLL01_EXPORTS
#include "dll01.h"
void dll01Func00()
{
printf("In [%s]\n", __FUNCTION__);
}
dll00_v1.c: (modified dll00_v0.c):
#include <inttypes.h>
#if defined(_WIN32)
# define DLL00_EXPORT_API __declspec(dllexport)
#else
# define DLL00_EXPORT_API
#endif
#include "dll01.h"
DLL00_EXPORT_API size_t dll00Func00()
{
dll01Func00();
return sizeof(void*);
}
Output:
[prompt]> :: Still building for pc032 from previous vcvarsall call [prompt]> [prompt]> cl /nologo /DDLL dll01.c /link /NOLOGO /DLL /OUT:dll01_032.dll dll01.c Creating library dll01_032.lib and object dll01_032.exp [prompt]> cl /nologo /DDLL dll00_v1.c /link /NOLOGO /DLL /OUT:dll00_032.dll dll00_v1.c Creating library dll00_032.lib and object dll00_032.exp dll00_v1.obj : error LNK2019: unresolved external symbol __imp__dll01Func00 referenced in function _dll00Func00 dll00_032.dll : fatal error LNK1120: 1 unresolved externals [prompt]> [prompt]> cl /nologo /DDLL dll00_v1.c /link /NOLOGO /DLL /OUT:dll00_032.dll dll01_032.lib dll00_v1.c Creating library dll00_032.lib and object dll00_032.exp [prompt]> [prompt]> "e:\Work\Dev\VEnvs\py_pc032_03.07.09_test0\Scripts\python.exe" code00.py dll00_032 Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:01:55) [MSC v.1900 32 bit (Intel)] 032bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll00_032.dll] In [dll01Func00] dll00Func00 returned 4 Done. [prompt]> :: Messing up dll01_032.dll [prompt]> echo garbage> dll01_032.dll [prompt]> "e:\Work\Dev\VEnvs\py_pc032_03.07.09_test0\Scripts\python.exe" code00.py dll00_032 Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 18:01:55) [MSC v.1900 32 bit (Intel)] 032bit on win32 Attempting to load: [e:\Work\Dev\StackOverflow\q057187566\dll00_032.dll] Traceback (most recent call last): File "code00.py", line 25, in <module> rc = main(*sys.argv[1:]) File "code00.py", line 14, in main dll00 = ct.CDLL(dll_name) File "c:\Install\pc032\Python\Python\03.07.09\lib\ctypes\__init__.py", line 364, in __init__ self._handle = _dlopen(self._name, mode) OSError: [WinError 193] %1 is not a valid Win32 application
Stating the obvious: Same error would occur if instead of writing garbage data into dll01_032.dll, I would have build it for 064bit, but I chose this variant as it's shorter.
Everything that I'll state in each of the next bullets, also applies to the ones that follow it.
Summarizing:
Make sure that:
otherwise, ending up in this (nasty) situation is (almost) certain.
Some real life scenario steps leading here:
Installing a software (Python - in this case)
Installing (creating, building) some kind of plugin (that contains .dlls) for that software (an (extension) module - in this case)
Although in general this kind of check is performed at install time, one needs to check (as already stated), that the CPU architectures of the (above) 2, must match.
If that doesn't happen, change one to match the other, and whenever possible (as there might be some (few) cases when it isn't), aim for 064bit (as it doesn't have many of 032bit's limitations). In this case install (and run) Python 064bit).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With