2014-01-22 54 views
1

我想使用ctypes的蟒蛇移动值的列表下的列表,我的计划是第一个指针传递到列表中,在C改造它。移动从蟒蛇到C

因此,在蟒蛇:

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出来,任何想法,为什么?

我也开放其他方式来做到这一点。

回答

2

无法打印double这种方式; %d仅适用于整数。您需要使用floating point conversion specifiers之一,如%f

printf("%f\n",*pointer); 

您应该考虑提高编译器的警告级别。许多现代编译器可以对此提出警告。

2

正确的属性名称是argtypesargtype

一个CPython的列表的元素是PyObject *,各定点处的任意地址分配(只要你关心)的对象。至少该对象有一个引用计数和指向该类型的指针。对于一个Python float此之后由C double价值,并为2.X int它的C long值。

你是不是传递一个“第一指针列表”,这是没有意义的。 pi是一个指向新创建的缓冲区的转换后的双倍值test[0]。我也不知道你为什么通过这个指针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 */ 
} 

您需要包括阵列的长度作为参数,如果它不是一个已知的大小。

+0

感谢啊,虽然我得到的错误 'test_arr =(ctypes.c_float * LEN(试验))(*测试)'' 类型错误:浮子required' 即使我改变了一切上浮 –

+0

其确定我设法解决这个问题,因为我正在读取一个文件,它将它存储为一个字符串列表。 –