2012-07-18 92 views
0

我想要做的是将C函数转换为python函数。如何在调用函数时返回ctyps中的数组

例如,我有一个C函数原型其中预先定义:

function_test(ViInt32 Arraysize, ViReal64 readingArray[], ViInt32 *Actual_rraysize) 

上述功能的输入是Arraysize,这是在readingArray参数元素的数量。

上述功能的输出为readingArray[]ArraysizereadingArray[]返回结果数组,Actual_arraysize指示返回数组的实际大小。

而下面是Python的功能我写了使用此C函数原型:

from ctypes import * 
def Py_function_test(self, arraysize, readingarray = [], actualarraysize = [-1e-10]): 
    while len(readingarray) < arraysize: 
     readingarray.append(0) 
    _c_actualarraysize = c_int() 
    ArrayOfDouble = c_double * arraysize 
    _c_readingarray = ArrayOfDouble() 
    self.function_test(c_int(arraysize), 
         byref(_c_readingarray), 
         byref(_actualarraysize)) 
    for n in range(arraysize): 
     readingarray[n] = _c_readingarray[n] 
    actualarraysize[0] = _c_actualarraysize.value 

最终,原来的acutalarraysize值更改成功。但拨打c function prototypereadingarray的值没有变化。

如何处理这种情况,是因为我不应该使用byref

回答

1

是的,传递数组时不需要byref。使用列表作为默认参数值将导致意外的错误。您可以在Python函数中返回数组和实际大小。

这里是我的代码:

from ctypes import * 
test = cdll.LoadLibrary("test") 
test.function_test.argtypes = [ 
    c_int, POINTER(c_double), POINTER(c_int) 
] 

def Py_function_test(arraysize): 
    _c_readingarray = (c_double*arraysize)() 
    _c_actualarraysize = c_int() 
    test.function_test(arraysize, _c_readingarray, byref(_c_actualarraysize)) 
    return _c_readingarray, _c_actualarraysize.value 

array, size = Py_function_test(10) 
print list(array), size 

的C代码:

void function_test(int Arraysize, double readingArray[], int *Actual_rraysize) 
{ 
    int i; 
    *Actual_rraysize = Arraysize/2; 
    for(i=0;i<*Actual_rraysize;i++) 
     readingArray[i] = i; 
} 

和Python代码的输出是:

[0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0] 5 
+0

我不知道是什么问题,但是在我尝试了你的方法之后,'_c_readingarray'的值仍然不会改变。 – 2342G456DI8 2012-07-18 07:52:55

+0

你确定c函数改变了readingArray的内容吗?我添加了测试c代码。请将c代码编译到test.dll中,并尝试使用我的python代码。 – HYRY 2012-07-18 08:24:32

+0

非常感谢,终于找出问题所在。这是'dll'的问题,而不是python的实现,但是你教给我的东西对我来说非常有用。 – 2342G456DI8 2012-07-18 09:45:50