Passing Numpy arrays to a C function for input and output

While not a direct answer to your original question, here’s a much more convenient way to call your function. First, make the prototype of your C function exactly as you would do it in plain C. Since you don’t need rowcount and colcount separately, I’ll collapse them into a single size parameter:

void cfun(const double *indatav, size_t size, double *outdatav) 
{
    size_t i;
    for (i = 0; i < size; ++i)
        outdatav[i] = indatav[i] * 2.0;
}

Now define the ctypes prototype in the following way:

import ctypes
from numpy.ctypeslib import ndpointer
lib = ctypes.cdll.LoadLibrary("./ctest.so")
fun = lib.cfun
fun.restype = None
fun.argtypes = [ndpointer(ctypes.c_double, flags="C_CONTIGUOUS"),
                ctypes.c_size_t,
                ndpointer(ctypes.c_double, flags="C_CONTIGUOUS")]

Now, calls to your function will be really convenient:

indata = numpy.ones((5,6))
outdata = numpy.empty((5,6))
fun(indata, indata.size, outdata)

You could also define a wrapper to make this even more convenient:

def wrap_fun(indata, outdata):
    assert indata.size == outdata.size
    fun(indata, indata.size, outdata)

Leave a Comment