错误提示:
加载完dll,调用dll中函数时提示ValueError: Procedure probably called with too many arguments (8 bytes in excess)。
C代码,编译成32bit dll文件:
// juzicode.com/ VX: 桔子code
#include "stdio.h"
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) int addint(int x, int y)
{
return x + y;
}
#ifdef __cplusplus
}
#endif
Python代码:
# juzicode.com/ VX: 桔子code
from ctypes import *
import os,sys,platform
print('sys.version:',sys.version)
add_path = os.path.split(os.path.abspath(__file__))[0]+'\\'
pyt = WinDLL(add_path+'pytest.dll')
pyt.addint.restype=c_int
pyt.addint.argtypes=(c_int,c_int)
z = pyt.addint(10,20)
print('z =',z)
==========运行结果:
sys.version: 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]
Traceback (most recent call last):
File "ctypes-test3.py", line 12, in
z = pyt.addint(10,20)
ValueError: Procedure probably called with too many arguments (8 bytes in excess)
错误原因:
1、C代码中默认是__cdecl调用约定,但是在Python中用的是WinDLL方式加载dll文件,所以导致出错。
解决方法:
1、C代码中的约定方式必须要和Python加载DLL的方式一致,pyt = WinDLL(add_path+’pytest.dll’)改为pyt = CDLL(add_path+’pytest.dll’):
# juzicode.com/ VX: 桔子code
from ctypes import *
import os,sys,platform
print('sys.version:',sys.version)
add_path = os.path.split(os.path.abspath(__file__))[0]+'\\'
#pyt = WinDLL(add_path+'pytest.dll')
pyt = CDLL(add_path+'pytest.dll') ###改为CDLL
pyt.addint.restype=c_int
pyt.addint.argtypes=(c_int,c_int)
z = pyt.addint(10,20)
print('z =',z)
==========运行结果:
sys.version: 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]
z = 30
注:上述错误多见于32bit Python加载32bit DLL文件时,测试过64bit Python3.6和3.8用WinDLL加载64bit dll模块并不会报错,但是最好按照ctypes约定的方式加载DLL文件。
# juzicode.com/ VX: 桔子code
from ctypes import *
import os,sys,platform
print('sys.version:',sys.version)
add_path = os.path.split(os.path.abspath(__file__))[0]+'\\'
pyt = WinDLL(add_path+'pytest.dll')
#pyt = CDLL(add_path+'pytest.dll')
pyt.addint.restype=c_int
pyt.addint.argtypes=(c_int,c_int)
z = pyt.addint(10,20)
print('z =',z)
sys.version: 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)]
z = 30
扩展内容:
- Python进阶教程m7–混合编程–调用可执行文件
- Python进阶教程m7b–混合编程–C语言接口ctypes(1)
- Python进阶教程m7c–混合编程–C语言接口ctypes(2)
- Python进阶教程m7d–混合编程–代码级扩展
如果本文还没有完全解决你的疑惑,你也可以在微信公众号“桔子code”后台给我留言,欢迎一起探讨交流。