我想使用 ctypes 将值列表从 python 移动到 C,我的计划是将第一个指针传递给列表并在 c 中重新制作它。
所以在 python 中:
test = [1,2,3]
Circuit.cCore.Add_Interpolation.argtype = [ctypes.c_int,
ctypes.POINTER(ctypes.c_double)]
i = ctypes.c_double(test[0])
pi = ctypes.pointer(i)
self.cCoreID = Circuit.cCore.Add_Interpolation(machine.cCoreID, ctypes.byref(pi))
然后在 C 中:
int Add_Interpolation(int owner, double* pointer)
{
printf("%d \n", *pointer);
}
我一直收到 40075424,知道为什么吗?
我也乐于采用其他方式。
最佳答案
正确的属性名称是 argtypes
而不是 argtype
。
CPython 列表的元素是 PyObject *
,每个元素都指向分配在任意地址的对象(就您而言)。该对象至少有一个引用计数和指向该类型的指针。对于 Python float
,后面跟着 C double
值,对于 2.x int
,它是 C long
值。
您没有传递“指向列表的第一个指针”,这是没有意义的。 pi
是指向为 test[0]
的转换 double 值新建的缓冲区的指针。我也不知道您为什么要传递此指针 byref
。 ctypes 应该在那里引发异常:
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>:
expected LP_c_double instance instead of pointer to LP_c_double
然而,这不是因为您设置了 argtype
而不是正确的属性名称 argtypes
。所以没有类型检查。
要将数字列表传递给 C 函数,您需要 ctypes 将连续数组中的对象转换为所需的 C 类型,例如 double
。使用 *
运算符创建数组类型以进行序列重复,例如c_double * 10
用于长度为 10 的数组。
Circuit.cCore.Add_Interpolation.argtypes = [ctypes.c_int,
ctypes.POINTER(ctypes.c_double)]
test = [1,2,3]
test_arr = (ctypes.c_double * len(test))(*test)
self.cCoreID = Circuit.cCore.Add_Interpolation(machine.cCoreID,
test_arr)
C:
int Add_Interpolation(int owner, double *pointer)
{
printf("%f\n", *pointer); /* print first double */
}
如果数组的大小未知,则需要将数组的长度作为参数包含在内。
关于python - 将列表从 python 移动到 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21285938/