3

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

蟒蛇文件:

from ctypes import *

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

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

已解决:问题是错误的调用约定。

4

1 回答 1

6

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

int DLL_EXPORT TestFunction(int data);

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

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

  1. 将 C 代码中的调用约定更改为stdcall(在 Windows 系统 DLL 中使用)。如果您使用的是 MSVC,他们有一个关于开发 DLL 的文档
  2. 将 Python 代码预期的调用约定更改为cdecl. 这是通过使用cdll代替来完成的windll
于 2012-08-02T02:34:11.420 回答