Python错误集锦:ctypes调用dll中函数时提示ValueError: Procedure probably called with too many arguments (8 bytes in excess)

原文链接:http://www.juzicode.com/archives/5143

错误提示:

加载完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

扩展内容:

  1.  Python进阶教程m7–混合编程–调用可执行文件
  2. Python进阶教程m7b–混合编程–C语言接口ctypes(1)
  3. Python进阶教程m7c–混合编程–C语言接口ctypes(2)
  4. Python进阶教程m7d–混合编程–代码级扩展 

 


 

如果本文还没有完全解决你的疑惑,你也可以在微信公众号“桔子code”后台留言撩我,我会尽我所能为你答疑解惑。

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注