Ctypes "期望的LP_c_double实例而不是元组"



我有一个C扩展,我想从Python调用。C扩展接受一个指向指针数组的指针和三个指向int64_t值数组的指针。我使用用C编写的包装器调用这个C扩展,下面是我如何在C中(在相关部分):

int64_t ptr_array_out[3];
int64_t *ptr_array_ptr = ptr_array_out;
ptr_array_out[0] = (int64_t)file_ptr1;
ptr_array_out[1] = (int64_t)file_ptr2;
int64_t type_array_out[3];
int64_t *ptr_type_array_ptr = type_array_out;
type_array_out[0] = 4; // double_precision
type_array_out[1] = 4; // double_precision
int64_t length_array_out[3];
int64_t *length_array_ptr = length_array_out;
length_array_out[0] = file_info[0];
length_array_out[1] = file_info[1];
int64_t s_data_out[3];
int64_t *s_array_ptr = s_data_out;
s_data_out[0] = 300

现在我在ctypes中复制它。唯一的区别是,第一个数组(ptr_array_ptr)传递的是指向内存中的数组的指针数组,而不是文件指针。以下是我到目前为止所做的:

ptr_array_ptr = (ctypes.c_double * len(q))(*q), (ctypes.c_double * len(z))(*z)
ptr_type_array_ptr = (ctypes.c_longlong(4)),(ctypes.c_longlong(4))
length_array_ptr = (ctypes.c_longlong(len(q))), (ctypes.c_longlong(len(z)))
s_array_ptr = (ctypes.c_longlong(maxval1)), (ctypes.c_longlong(maxval2))
hShObj = ctypes.CDLL("(pathto shared obj)/SharedObjName.so")
CallName = hShObj.Main_Entry_fn
CallName.argtypes = [ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_longlong),ctypes.POINTER(ctypes.c_longlong),ctypes.POINTER(ctypes.c_longlong)]
CallName.restype = ctypes.POINTER(ctypes.c_int64)
ret_ptr = CallName(ptr_array_ptr, ptr_type_array_ptr, length_array_ptr, s_array_ptr)

但是我从Python得到这个错误:

ctypes.ArgumentError: argument 1: <class 'TypeError'>: expected LP_c_double instance instead of tuple

我研究了这个问题,并在Stack Overflow和其他地方的各种上下文中找到了几个答案,但没有一个解决这个特定情况。我不是一个ctypes新手,但我已经好几年没有使用它了,所以我不知道如何解决这个问题。

非常感谢你的帮助。

清单[Python。ctypes - Python的外部函数库。

您正在创建元组(由于逗号s ()))的4个元素。检查(Python。[文档]:数据结构-元组和序列。

修复方法是创建一个2D数组。不幸的是,我不知道一个优雅的初始化方法,所以我使用了2个嵌套的循环:
>>> import ctypes as ct
>>>
>>>
>>> q = [1, 2, 3]
>>> z = [4, 5, 6, 7]
>>>
>>> ptr_array_ptr = (ct.c_double * len(q))(*q), (ct.c_double * len(z))(*z)  # @TODO - cfati: this is a tuple
>>> ptr_array_ptr
(<__main__.c_double_Array_3 object at 0x000001444D9A7EC0>, <__main__.c_double_Array_4 object at 0x000001444D9C2340>)
>>> type(ptr_array_ptr)
<class 'tuple'>
>>> [type(e) for e in ptr_array_ptr]
[<class '__main__.c_double_Array_3'>, <class '__main__.c_double_Array_4'>]
>>>
>>> ptr_array_ptr[0][0], ptr_array_ptr[1][0]
(1.0, 4.0)
>>>
>>> # Start over
>>> lists = (q, z)
>>> max_len = max(len(e) for e in lists)
>>> max_len
4
>>> Arr = (ct.c_double * max_len) * len(lists)  # Array type
>>> Arr
<class '__main__.c_double_Array_4_Array_2'>
>>>
>>> arr = Arr()  # array
>>> arr
<__main__.c_double_Array_4_Array_2 object at 0x000001444D9C22C0>
>>> arr[0][0], arr[1][0], arr[0][2], arr[1][2], arr[0][3], arr[1][3]
(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
>>>
>>> for i0, l in enumerate(lists):
...     for i1, c in enumerate(l):
...         arr[i0][i1] = c
...
>>>
>>> arr[0][0], arr[1][0], arr[0][2], arr[1][2], arr[0][3], arr[1][3]
(1.0, 4.0, 3.0, 6.0, 0.0, 7.0)

最新更新