user1685095
user1685095

Reputation: 6121

What is the most efficient way to pass numpy array to c++ function and return numpy array as output?

I've created a shared library. And I'm using it like that

class CAudioRecoveryStrategy(AbstractAudioRecoveryStrategy):
    def __init__(self):
        array_1d_double = npct.ndpointer(dtype=numpy.double, ndim=1, flags='CONTIGUOUS')
        self.lib = npct.load_library("libhello", ".")

        self.lib.demodulate.argtypes = [array_1d_double, array_1d_double, ctypes.c_int]

    def demodulate(self, input):
        output = numpy.empty_like(input)
        self.lib.demodulate(input, output, input.size)
        return output

Right now I have a problem, which is in c++ code I only have pointer to array of output data, not the array. So I can't return the array, unless I manually copy it.

What is the right way to do it? It must be efficient (like aligned memory etc.)

Upvotes: 2

Views: 615

Answers (1)

James Kanze
James Kanze

Reputation: 153919

Numpy arrays implement the buffer protocol, see https://docs.python.org/2/c-api/buffer.html. In particular, parse the input object to a PyObject* (conversion O if you're using PyArg_ParseTuple or PyArg_ParseTupleAndKeywords), then do PyObject_CheckBuffer, to ensure that the type supports the protocol (numpy arrays do), then PyObject_GetBuffer to fill in a Py_buffer struct with the physical addresses, dimensions, etc. of the underlying memory block. To return a numpy buffer is more complicated; in general, I've found it sufficient to create objects of my own type which also support the buffer protocol (set tp_as_buffer to non null in the PyTypeObject). Otherwise (but I've not actually tried this), you'll have to import the numpy module, get its array attribute, call it with the correct arguments, and then use the buffer protocol above on the object you thus construct.

Upvotes: 2

Related Questions