3

I am trying to write code that wraps a C library in python. I am planning on using CTypes to do it and I used visual studio to compile my DLL. I started with a simple function and I added the following in a header within Visual Studio that was then built to a DLL

int our_function(int num_numbers, int* numbers) {
    int i;
    int sum = 0;
    for (i = 0; i < num_numbers; i++) {
        sum += numbers[i];
    }
    return sum;
}

My python wrapper is the following

import ctypes

_sum = ctypes.CDLL(r"C:\Users\spl\Desktop\Ctypes Testing\Ctypes tester 2.dll")
_sum.our_function.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_int))

def our_function(numbers):
    global _sum
    num_numbers = len(numbers)
    array_type = ctypes.c_int * num_numbers
    result = _sum.our_function(ctypes.c_int(num_numbers), array_type(*numbers))
    return int(result)

print(sum.our_function([1,2,-3,4,-5,6]))

When I execute the python code I get the following error

Traceback (most recent call last):
  File "sum.py", line 3, in <module>
    _sum = ctypes.CDLL(r"C:\Users\spl\Desktop\Ctypes Testing\Ctypes tester 2.dll")
  File "C:\Users\spl\anaconda3\envs\Blank tester\lib\ctypes\__init__.py", line 364, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 is not a valid Win32 application

What causes this error and how do I fix it? I am using a 64 bit machine with windows 10 and my python build is 64 bit. I don't know much C, and the main goal is to get it working so that I can code everything in python.

CristiFati
  • 38,250
  • 9
  • 50
  • 87
  • Please provide a hex dump of the first 512 bytes or so of `C:\Users\spl\Desktop\Ctypes Testing\Ctypes tester 2.dll`. (Do this by editing your question. Did you know you can edit your question? The tiny gray word "edit" under the tags is a button. Yes, it's bad UI design. Sorry about that.) – zwol Jul 04 '20 at 15:20
  • It would also be interesting to know what happens if you call [`LoadLibrary`](https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya) on this DLL from a C++ program compiled by the same copy of Visual Studio. – zwol Jul 04 '20 at 15:21

1 Answers1

2

This is a typical CPU architecture (032bit (your .dll) vs. 064bit (Python process that tries to load it)) mismatch. Check [SO]: Python Ctypes - loading dll throws OSError: [WinError 193] %1 is not a valid Win32 application (@CristiFati's answer) for more details.

Build the 064bit (pc064) version of your your .dll.
You can use the command line tools from the aforementioned URL, or you can set the VStudio IDE to do it, as explained in [MS.Docs]: How to: Configure Visual Studio C++ projects to Target 64-Bit, x64 Platforms:

  1. Open the C++ project that you want to configure.
  2. Open the property pages for that project. For more information, see Set C++ compiler and build properties in Visual Studio.
  3. Choose the Configuration Manager button to open the Configuration Manager dialog box.
  4. In the Active Solution Platform drop-down list, select the <New...> option to open the New Solution Platform dialog box.
  5. In the Type or select the new platform drop-down list, select a 64-bit target platform.
  6. Choose the OK button. The platform that you selected in the preceding step appears under Active Solution Platform in the Configuration Manager dialog box.
  7. Choose the Close button in the Configuration Manager dialog box, and then choose the OK button in the <Projectname> Property Pages dialog box.
CristiFati
  • 38,250
  • 9
  • 50
  • 87