2012-08-02 71 views
3

我试着写,我可以在Python(2.7)导入一个DLL,我有苦衷“使其工作”。当我使用WinDLL()windll.LoadLibrary()加载在Python库,并测试导出函数的输出我得到的是空的。如果我加一个参数TestFunction()它提出了一个ValueError其中指出,有可能是许多参数(这真的不是)。使用与Python(使用ctypes的)一个DLL,没有工作

蟒蛇文件:

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

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

+0

我没有直接回答你的问题/问题,但如果你想使Python模块,我会建议Boost.Python的。只是一个想法。 – DubyaDubyaDubyaDot 2012-08-02 02:21:18

+0

你能粘贴确切的错误吗?我认为它应该指定一些多余/丢失的字节。 – 2012-08-02 02:26:02

+0

确切的错误是 'ValueError异常:程序可能有太多的参数调用(超过4个字节)' – JHolta 2012-08-02 03:22:52

回答

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来完成的。
相关问题