What is the canonical way of getting a numpy matrix as an argument to a C function which takes a double pointer?
Context: I'm using numpy
to validate some C code-to wit, I have a C function which takes a const double ** const
, and I'm using ctypes
to call the .so
from Python.
I've tried:
func.argtypes = ctypeslib.ndpointer(dtype=double, ndim=2, flags="C_CONTIGUOUS")
and passed the numpy
matrix directly (didn't work), as well as
func.argtypes = ctypes.POINTER(ctypes.POINTER(ctypes.c_double))
and then passed the numpy
matrix via various casts. Casting led to the Python error
TypeError: _type_ must have storage info
Note: This question came up a few years ago here, but there was no completely successful resolution.
I think you're looking for the ctypes
interface in numpy's ndarray
s (or matrix
for that matter). You may have a look here for more information on numpy's manual.
Please note that numpy C-API stores ndarray
s (or matrices for that matter) with a single pointer (see http://docs.scipy.org/doc/numpy/reference/c-api.types-and-structures.html#c.PyArrayObject). You cannot convert this single pointer into a double pointer in C, just because these are different types. Furthermore, numpy not only stores the data on these objects, it also stores information about the shape of the matrix and the strides (how the data is organised on the provided data pointer). Without knowing all these information, your code will not work on all conditions. For example, if you transpose a matrix before interfacing it to your code, you'll get unexpected results!
There are a couple of solutions depending on your settings:
If you can modify your library's API, change it so that you can pass numpy information concerning not only the data pointer, but also the shape of the matrix and its strides. Then, use the above link to figure out how to interface numpy/ctypes support with your new API.
If you cannot modify your API, I suggest you create a Python function based on ctypes that converts the contents of the numpy array into a double-pointer matrix created with ctypes itself (as suggested on this discussion). Also add support for the numpy object shape and stride so that you can run the conversion properly. After converting, pass the newly created double pointer structure to your original function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With