Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

array output from Python ctypes?

Tags:

c++

python

ctypes

I need to call a C function from Python, using ctypes and to have that function provide one or more arrays back to Python. The arrays will always be of simple types like long, bool, double.

I would very much prefer if the arrays could be dynamically sized. I will know the needed before each call, but different call should use different sizes.

I suppose I should allocate the arrays in Python and let the C code overwrite the contents, so that Python can eventually de-allocate the memory it allocated.

I control both the Python and the C code.

I have this now which does not work:

C:

FOO_API long Foo(long* batch, long bufferSize)
{
    for (size_t i = 0; i < bufferSize; i++)
    {
        batch[i] = i;
    }
    return 0;
}

Python:

print "start test"
FooFunction = Bar.LoadedDll.Foo
longPtrType = ctypes.POINTER(ctypes.c_long)
FooFunction.argtypes = [longPtrType, ctypes.c_long]
FooFunction.restype = ctypes.c_long

arrayType = ctypes.c_long * 7
pyArray = [1] * 7
print pyArray
errorCode = FooFunction(arrayType(*pyArray), 7)
print pyArray
print "test finished"

Produces:

start test
[1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1]
test finished

Should Produce:

start test
[1, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 5, 6]
test finished

Why does this not work? Or do I need to do this in a different way?

like image 581
ThomasI Avatar asked May 27 '26 10:05

ThomasI


1 Answers

The C array is built using the python list; both are different objects. And the code is print the python list, which is not affected by Foo call.

You need to build the C array, pass it, then use it after the call:

arrayType = ctypes.c_long * 7
array = arrayType(*[1] * 7)
print list(array)
errorCode = FooFunction(array, len(array))
print list(array)
like image 178
falsetru Avatar answered Jun 03 '26 22:06

falsetru