Exposing an array interface with SWIG for a C/C++ structure

Sometimes, a C or C++ array structure must be used in Python, and it’s always better to be able to use the underlying array to do some Numpy computations. To that purpose, Numpy proposes the array interface.

I will now expose an efficient way to use SWIG to generate the array interface and exposing the __array_struct__ property.
Let’s start with a simple C structure (what is really relevant is that the structure encompasses an arrau). If you don’t have the strides and the shape, you will have to add them to the structure (create a new structure with the structure to wrap inside, for example):

This is the main function which will create the Numpy array interface from the structure. Its parameters are the to-be-wrapped object as well as every other argument like the shape, the stride or the actual data. Once an interface is created, it is populated with appropriate values (like the data type) and then the function PyCObject_FromVoidPtrAndDesc() will be called to create the sought Python object.

I’ve added a sample for the __str__() function which returns a static character array. You could return a std::string for more robustness.

The last feature is %pythoncode. It indicates to SWIG that it should copy and paste the code directly in the Python wrapper. I had to do this because __array_struct__ must be a Python property. Furthermore, the property getter can’t be the SWIG function. This is because SWIG does not wrap objects directly, but uses classic Python functions, and as a consequence, the first argument of the C function can’t be used.

The underlying C function must have access to the Python wrapper object to correctly count the reference on the object. To do, the object must be passed as a usual argument, which is what the intermediate method __array_struct__get() does.