使用DLL与python(使用ctypes),不工作

时间:2012-08-02 01:20:05

标签: c++ python dll ctypes

我正在尝试编写一个可以在Python(2.7)中导入的DLL,并且我遇到了“让它工作”的困难。当我使用WinDLL()windll.LoadLibrary()在Python中加载库时,测试导出的函数时,我得到的输出为空。如果我向TestFunction()添加一个参数,它会引发一个ValueError,表明可能有很多参数(实际上并非如此)。

蟒文件:

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

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;
}

解决:问题调用约会错误。

1 个答案:

答案 0 :(得分:6)

我的第一个猜测是你使用的是与Python假设不同的调用约定。

int DLL_EXPORT TestFunction(int data);

该声明可能意味着将使用cdecl调用约定;使用windll时,Python认为应该使用stdcall约定。这有效地改变了参数传递的方式,从而使Python相信您传递了错误数量的参数。这在ctypes documentation

中注明

如果是这种情况,您可以执行以下任一操作:

  1. 将C代码中的调用约定更改为stdcall(在Windows系统DLL中使用)。如果您使用的是MSVC,则会有a doc on developing DLLs;
  2. 将Python代码期望的调用约定更改为cdecl。这是通过使用cdll代替windll来完成的。