如何创build一个DLL库的Python包装

我想从一个软件SDK中提供的DLL文件,并创build一个Python包装,以便与我的代码库的其余部分进行整合。 我在网上跟着不less指南,还没有运气。

目前的Python代码是:

from ctypes import * from ctypes.wintypes import HWND import os class OptistarDLL(object): dll_path = 'OSDS142MRT.dll' with open(dll_path) as thefile: pass _dll = WinDLL(dll_path) init_library = _dll['OSDS142M_Initialize'] init_library.restype = c_int init_library.argtypes = (c_int, c_bool, HWND, c_bool, c_int) class OpticstarControl(object): def __init__(self): err = OptistarDLL.init_library(c_int(0), c_bool(False), HWND(0), c_bool(False), c_int(0)) if err != 0: raise Exception("Doom") 

我正在使用的SDK文档提供了这个函数的头文件:

 DLLDIR int OSDS142M_Initialize(int iModel, bool bOutVid, HWND hwOutVid, bool bStarView, int iRt); 

PDF示例给出了:

 OSDS142M_Initialize(1, false, 0, true, 0); 

初始化目前只有我

 ValueError: Procedure probably called with too many arguments (20 bytes in excess) 

我已经阅读,但没有理解,有关WinDLLCDLL ,并加载的DLL失败,当我改变为CDLL 。 我也在所有的指南中看到,其中的标题有DLLDIR ,而我的DLLDIR ,我不知道这是否是一个问题。

有没有人有任何想法?

考虑到问题中的信息,最可能的解释是该DLL使用cdecl而不是stdcall 。 您使用WinDLL匹配一个stdcall DLL。 改为使用CDLL切换到cdecl调用约定。

错误消息与此一致。 调用约定之间的区别是stdcall有被调用的堆栈清理,而cdecl有调用者清理。 这些参数在堆栈上占用20个字节,大小为4的5个参数.ctypes将这些参数推入,期望被调用者清理堆栈。 这不是因为它是一个cdecl函数。

你对这个函数的调用是非常复杂的。 你可以写:

 err = OptistarDLL.init_library(0, False, 0, False, 0) 

请注意,您引用的示例调用会传递不同的参数。 要匹配这个电话,你会写:

 err = OptistarDLL.init_library(1, False, 0, True, 0) 

你当然应该删除这个代码:

 with open(dll_path) as thefile: pass 

除了浪费时间之外,这没有任何用处。 如果DLL不存在,您将很快遇到失败。