2342G456DI8
2342G456DI8

Reputation: 1809

How to return an array in ctyps when calling a function

What I want to do is to convert a C function into python function.

For example, I have a C function prototype which is pre-defined:

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

The input of the above function is Arraysize, which is the number of elements in the readingArray parameter.

The outputs of the above function are readingArray[] and Arraysize. readingArray[] returns an array of the result and Actual_arraysize indicates the actual size of the returned array.

And the following is the Python function I wrote by using this C function prototype:

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

In the end, it turned out the value of acutalarraysize is successfully changed. But the value of readingarray didn't change after calling the c function prototype.

How to deal with this situation, is it because I should not have used the byref?

Upvotes: 0

Views: 351

Answers (1)

HYRY
HYRY

Reputation: 97331

Yes, you don't need byref when passing array. And using list as default argument values will cause unexpected bugs. You can return the array and the actualarrysize in your Python function.

Here is my code:

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

the c code:

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;
}

and the output of python code is:

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

Upvotes: 1

Related Questions