Python调用Fortran DLL遇ctypes.ArgumentError:无法转换参数1求助
问题解决方法
错误原因
- Python普通列表无法直接映射到Fortran的
real(8)数组类型,ctypes无法自动完成转换。 - 输出参数
objf用普通Python浮点数传递,属于不可变类型,无法被Fortran子程序修改,也不符合参数传递规则。 - 未明确指定Fortran子程序的参数类型(
argtypes),ctypes无法正确推导参数转换逻辑。
修改后的Python代码
import ctypes as ct # 加载编译好的Fortran DLL lib = ct.CDLL('x64\\Debug\\main2.dll') # 获取导出的Fortran子程序(名称需和DLL实际导出的一致) f = getattr(lib, 'MAIN2_MOD_mp_MAIN2') # 设置子程序返回类型(Fortran子程序无返回值) f.restype = None # 明确指定参数类型:第一个是c_double指针(对应Fortran的real(8)数组),第二个是c_double指针(输出参数) f.argtypes = [ct.POINTER(ct.c_double), ct.POINTER(ct.c_double)] def fun(x): # 将Python列表转换为ctypes可识别的c_double数组 x_arr = (ct.c_double * len(x))(*x) # 创建可修改的c_double对象,用于接收Fortran输出的结果 objf = ct.c_double(0.0) # 调用子程序,数组直接传递(ctypes自动转为指针),输出参数用byref传递指针 f(x_arr, ct.byref(objf)) # 若需要获取修改后的x值,可通过x_arr[:]转换为Python列表 # 返回输出结果的数值 return objf.value # 测试调用 x = [2.0, 0.0] result = fun(x) print(result)
关键修改点说明
- 数组参数处理:将Python列表转为
ctypes.c_double数组,匹配Fortran的real(8)类型,数组传递时ctypes自动转为指针,对应Fortran的x(*)数组定义。 - 输出参数处理:用
ct.c_double()创建可修改的浮点数对象,通过ct.byref()传递指针,让Fortran子程序能修改其值,最终通过.value获取结果。 - 指定argtypes:明确参数类型是调用外部DLL的标准操作,避免ctypes自动推导出错。
额外注意事项
- Fortran编译器导出的子程序名称可能因编译器不同有差异(比如全小写、添加下划线),可以用Dependency Walker等工具查看DLL的实际导出名称。
- 如果Fortran子程序使用
stdcall调用约定,需用ct.WinDLL替代ct.CDLL加载DLL。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

