Eralde
Eralde

Reputation: 99

Passing arguments to functions from a dll loaded with ctypes

I'm trying to call from my Python code a simple function from a dll, build with QtCreator, and the problem is that argument size is always invalid.

Here's my test.h (test.cpp is empty):

#ifndef TEST_H
#define TEST_H

#include "test_global.h"

extern "C"
{

   int TESTSHARED_EXPORT si () { return sizeof(int);}

   int TESTSHARED_EXPORT add4 ( int i) { return i + 4;}
}


#endif // TEST_H

It builds to test.dll, which I'm able to load with:

tdll = windll.LoadLibrary(r'X:\TMP\SRC\build-test-Desktop_Qt_5_1_1_MinGW_32bit-Release\release\test.dll')

Calling print tdll.si() prints 4 as expected, but all calls to tdll.add4(1) fail with an error:

Traceback (most recent call last):
  File "test.py", line 29, in <module>
    print tdll.add4(2)
ValueError: Procedure probably called with too many arguments (4 bytes in excess)

Same thing happens if I wrap add4 argument into c_int, c_uint, c_int32 or any other *int type, provided by ctypes.

Please, help me fix this. Thanks!

Upvotes: 0

Views: 686

Answers (1)

David Heffernan
David Heffernan

Reputation: 613541

These are the symptoms of a calling convention mismatch. Probably your exported functions are __cdecl, but your ctypes code uses __stdcall. Your question does not have enough information for me to be sure of that but it's very likely and does explain the reported behaviour.

Resolve the mismatch by using cdll instead of windll. Using windll results in __stdcall being used, using cdll results in __cdecl being used.

Upvotes: 2

Related Questions