Python调用Fortran子程序添加argtypes后触发TypeError错误求助
Python调用Fortran子程序的ctypes类型匹配错误修复
问题场景
使用Python的ctypes调用Fortran编译生成的动态链接库,子程序接收1个字符输入参数和3个整型输出参数。未声明argtypes时程序能正常运行,但添加字符参数(含长度)和argtypes声明后触发TypeError。
原Python代码
import ctypes as ct import sys # 原代码遗漏该导入,需补充 lib = ct.CDLL('FTN_lib.dll') fs = getattr(lib,'PY_OBJFUN_MOD_mp_GETSIZE') fs.restype = None # 错误的argtypes声明 fs.argtypes = [ct.c_char_p,ct.c_int,ct.c_int,ct.c_int,ct.c_int] x = b'x ' + sys.argv[1].encode('UTF-8') + b' debug=900' n = ct.c_int(0) nl = ct.c_int(0) nnl = ct.c_int(0) fs(x, len(x), ct.byref(n), ct.byref(nl), ct.byref(nnl))
错误信息
fs(x, len(x), ct.byref(n), ct.byref(nl), ct.byref(nnl))ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type
Fortran子程序头
subroutine getsize(file,n,nl,nnl) implicit none character(*), intent(in ) :: file integer , intent(out) :: n integer , intent(out) :: nl integer , intent(out) :: nnl
错误原因
- 输出参数类型不匹配:Fortran中
intent(out)的整型参数,在C兼容的调用接口中需要传递指针(用于修改调用者的变量)。原argtypes中声明的是ct.c_int(值类型),但实际传递的是ct.byref(n)(指针类型),类型不匹配导致报错。 - 字符参数的处理是正确的:Fortran的
character(*)会自动在编译时添加长度参数作为第二个输入参数,对应代码中的len(x)。
修复后的代码
将argtypes中对应输出参数的类型改为ct.POINTER(ct.c_int),匹配ct.byref()传递的指针类型:
import ctypes as ct import sys lib = ct.CDLL('FTN_lib.dll') fs = getattr(lib,'PY_OBJFUN_MOD_mp_GETSIZE') fs.restype = None # 修正argtypes,输出参数声明为指针类型 fs.argtypes = [ct.c_char_p, ct.c_int, ct.POINTER(ct.c_int), ct.POINTER(ct.c_int), ct.POINTER(ct.c_int)] x = b'x ' + sys.argv[1].encode('UTF-8') + b' debug=900' n = ct.c_int(0) nl = ct.c_int(0) nnl = ct.c_int(0) fs(x, len(x), ct.byref(n), ct.byref(nl), ct.byref(nnl)) # 调用后可直接读取value属性获取输出结果 print(f"n: {n.value}, nl: {nl.value}, nnl: {nnl.value}")
验证说明
- 修正
argtypes后,参数类型与实际传递的指针完全匹配,不会再触发类型错误。 - Fortran编译为动态库时,若使用模块子程序,编译器会自动生成类似
PY_OBJFUN_MOD_mp_GETSIZE的别名,无需额外修改绑定规则。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

