我想从一个软件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)
我已经阅读,但没有理解,有关WinDLL
与CDLL
,并加载的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不存在,您将很快遇到失败。