3

I'm trying to write a DLL that I can import in Python (2.7), and I'm having difficulties "making it work". When I load the library in Python using WinDLL() or windll.LoadLibrary(), and test the exported function the output i get is empty. If I add an argument to TestFunction() it raises a ValueError which states that there is probably to many arguments (it's really not).

python-file:

from ctypes import *

x = windll.LoadLibrary('./pymod.dll')
print x.TestFunction(123) #Should return 123.

main.h:

#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
#define DLL_EXPORT __declspec(dllexport)    

#ifdef __cplusplus
extern "C"
{
#endif

int DLL_EXPORT TestFunction(int data);

#ifdef __cplusplus
}
#endif

#endif

and main.cpp:

#include "main.h"

int DLL_EXPORT TestFunction(int x = 0) {
    return x;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
    switch (fdwReason){
        case DLL_PROCESS_ATTACH:
            break;
        case DLL_PROCESS_DETACH:
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
    }
    return TRUE;
}

Solved: Issue was wrong calling convention.

5
  • I don't have a direct answer to your question/problem, but if you want to make Python modules, I would recommend Boost.Python. Just a thought. Commented Aug 2, 2012 at 2:21
  • Could you paste the exact error? I think it should specify a number of excess/missing bytes. Commented Aug 2, 2012 at 2:26
  • The exact error is ValueError: Procedure probably called with too many arguments (4 bytes in excess) Commented Aug 2, 2012 at 3:22
  • you can use my answer: stackoverflow.com/questions/7586504/… Commented Jan 19, 2013 at 14:04
  • why "./pymod.dll"? is it windows, linux, cygwin? Commented Mar 17, 2015 at 20:08

1 Answer 1

6

My first guess would be that you are using a different calling convention than your Python assumes.

int DLL_EXPORT TestFunction(int data);

That declaration probably means that cdecl calling convention will be used; while use of windll makes Python believe that the stdcall convention should be used. That effectively changes the way that arguments are passed, and thus makes Python believe that you have passed the wrong number of arguments. This is noted in the ctypes documentation.

If that's the case, you can do either of the following:

  1. Change the calling convention in the C code to stdcall (which is used in Windows system DLLs). If you are using MSVC, they have a doc on developing DLLs;
  2. Change the calling convention expected by the Python code to cdecl. This is done by using cdll instead of windll.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.