为什么我会收到此错误? <class 'TypeError'>:类型错误

问题描述 投票:0回答:1

我有一个调用 Fortran 子例程的 Python 驱动程序。该子例程有 1 个字符,然后是 3 个整数。在我在开始处添加字符变量并且没有 argtypes 调用之前,它运行良好。但是在开始时添加字符(及其长度)加上 artgtypes 调用会出现 TypeError:

import ctypes as ct
lib = ct.CDLL('FTN_lib.dll')
fs = getattr(lib,'PY_OBJFUN_MOD_mp_GETSIZE')
fs.restype = None
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:参数 3::类型错误

看来添加 fs.argtypes 导致了问题。测试代码没有这个,而且运行得很好。添加 fs.argtypes 也会导致测试代码失败。因此,使用 ct.c_int 构造在调用中用作 ct_byref 会出现一些问题。

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 
python fortran ctypes
1个回答
1
投票

Fortran 通过引用而不是值传递整数。

argtypes
对于整数参数应该是
ct.POINTER(ct.c_int)

注意:另一个答案的注释表示字符串大小在 32 位系统上应为 int32,在 64 位系统上应为 int64。我会用

c_size_t
。它还表示字符串长度被添加到参数列表的末尾而不是交错。我没有 Fortran 来测试。

尝试:

fs.argtypes = ct.c_char_p, ct.POINTER(ct.c_int), ct.POINTER(ct.c_int), ct.POINTER(ct.c_int), ct.c_size_t
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, ct.byref(n), ct.byref(nl), ct.byref(nnl), len(x))
© www.soinside.com 2019 - 2024. All rights reserved.