【发布时间】:2020-11-04 14:16:09
【问题描述】:
我的C函数的定义是-
foo(int64_t* total_length,
const int8_t* fromtags,
int64_t fromtagsoffset,
const int32_t* fromindex,
int64_t fromindexoffset,
int64_t length,
int64_t** offsetsraws,
int64_t* offsetsoffsets)
我可以通过ctypes 在Python 中加载它 -
import ctypes
lib = ctypes.CDLL("....")
name = "foo"
funcC = getattr(lib, name)
我可以设置它需要的参数类型 -
funcC.argtypes = (ctypes.POINTER(ctypes.c_int64), ctypes.POINTER(ctypes.c_int8), ctypes.c_int64, ctypes.POINTER(ctypes.c_int32), ctypes.c_int64, ctypes.c_int64, ctypes.POINTER(ctypes.POINTER(ctypes.c_int64)), ctypes.POINTER(ctypes.c_int64))
我分配要传递给 funcC 的值,例如 -
temparr = [0]*30
total_length = ((ctypes.c_int64)*30)(*temparr)
temparr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
fromtags = ((ctypes.c_int8)*len(temparr))(*temparr)
fromtagsoffset = 1
temparr = [1, 2, 6, 6, 3, 7, 3, 8, 3, 8, 8]
fromindex = ((ctypes.c_int32)*len(temparr))(*temparr)
fromindexoffset = 0
length = 3
temparr = [0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
offsetsoffsets = ((ctypes.c_int64)*len(temparr))(*temparr)
对于类型为指向指针的参数,我分配的值类似于 -
temparr = [1, 2, 1, 2, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
offsetsraws = ctypes.pointer((ctypes.c_int64 * len(temparr))(*temparr))
然后我用参数创建一个list -
testsc = [total_length, fromtags, fromtagsoffset, fromindex, fromindexoffset, length, offsetsraws, offsetsoffsets]
我终于将参数传递给funcC -
funcC(*testsc)
但我得到一个错误 -
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 7: <class 'TypeError'>: expected LP_LP_c_long instance instead of LP_c_long_Array_16
我应该如何解决这个错误?
是不是因为我在将offsetsraws argtype 分配为ctypes.POINTER(ctypes.POINTER(ctypes.c_int64)) 时出错了?
我发现了一个类似的问题 - Python and ctypes: how to correctly pass "pointer-to-pointer" into DLL?,但不同之处在于,在该问题中,传递的指针的指针在输入期间没有分配值,更重要的是,它没有表示为 2D 数组。
【问题讨论】: