Windell ctypes调用python 2.7中的可变c函数在win64中工作,但在win32中不工作
我正在Windows 10-32和Windows 10-64上使用Python 2.7 我正在为C编译的stdcall(Windows)DLL(=mydll)编写python包装。我有两个版本的DLL-32和64位。 使用Windell ctypes调用python 2.7中的可变c函数在win64中工作,但在win32中不工作,python,windows,ctypes,32bit-64bit,variadic-functions,Python,Windows,Ctypes,32bit 64bit,Variadic Functions,我正在Windows 10-32和Windows 10-64上使用Python 2.7 我正在为C编译的stdcall(Windows)DLL(=mydll)编写python包装。我有两个版本的DLL-32和64位。 使用windell.mydll时,64版本的效果非常好。 对于DLL上的所有函数,除了variadicprintf类函数外,32版本使用相同的命令工作得非常好 运行mydll.myvarfunc(“Hello”) 我明白了 ValueError:调用过程时可能有太多参数(超过4字节
windell.mydll
时,64版本的效果非常好。
对于DLL上的所有函数,除了variadicprintf
类函数外,32版本使用相同的命令工作得非常好
运行mydll.myvarfunc(“Hello”)
我明白了
ValueError:调用过程时可能有太多参数(超过4字节)
有没有一种方法不涉及更改可变函数的C代码?在Win64上,只有一个ABI,所以Windl和CDLL没有区别。在Win32上,可变函数总是
\uu cdecl
,因此Windell使用了错误的调用约定
解决此问题的一种方法:
import ctypes
stdcall_func = ctypes.WinDLL('mydll').stdcall_func
cdecl_func = ctypes.CDLL('mydll').cdecl_func
检查一下:您正在从32位Python调用您的32位DLL,是吗?在Win64上,只有一个ABI,所以Windl和CDLL没有区别。在Win32上,可变函数是cdecl而不是stdcall,因此Windell使用了错误的调用约定。BoarGules:我在32位python上使用32位dll是的。马克·托洛宁:我注意到,当我用CDLL加载文件时,可变函数可以工作,但其他函数不能。因此,您的建议是只加载两次文件-将Windell实例用于非变量,将CDLL实例用于变量?@jresing,请注意,创建
ctypes.CDLL
和ctypes.windell
实例不会物理加载DLL两次。它只是在内存中创建对同一DLL的第二个引用。或者,您可以创建单个cdecl函数指针。使用原型,例如fn\u cdecl\u p=ctypes.CFUNCTYPE(ctypes.c\u int)
。为每个函数实例化原型,并将其设置为mydll
的属性,例如setattr(mydll,'myvarfunc',fn_cdecl_p(('myvarfunc',mydll))
。