Search code examples
pythonc++cythonmemoryview

Cython example for sending array/vector to a c++ script


Say we have a 1 dimensional numpy array or list that we use as an input to a function, i.e., func(np.array[1.5, 2.5, 3.5]), where this function comes from a wrapped c++ class and our goal is to print the values of this array or vector inside the c++ script.

However, I don't know how to define the c++ function for this matter and specify it in the pyx file. And wanted to ask if you can share a snippet as simple as having the above functionality, where low latency is of most importance.

Basically, on the c++ side I want to do:

void func (/* where I don't what to write */) {

std::cout <<  array_[0] << std::endl; // which prints 1.5 (since np.array[1.5, 2.5, 3.5][0] was 1.5)
std::cout <<  array_[1] << std::endl; // which prints 2.5 (since np.array[1.5, 2.5, 3.5][1] was 2.5)
std::cout <<  array_[2] << std::endl; // which prints 3.5 (since np.array[1.5, 2.5, 3.5][2] was 3.5)
}

It seems memoryviews offer a possible solution that also has low latency, however looking at Cython's documentation about memoryviews, I'm quite confused.

The example from here mentions (int* a, int n) as the argument of the above function, but I didn't understant what a and n are about and how do I sill index the array on teh c++ side. And finally writing the pyx mirror is also unclear to me.

I would appreciate if anyone could give a very simple snippet example for such c++ function and it's pyx counterpart. Any suggestion other than memoryviews that is not slow is also greatly welcome:)


Solution

    • a is a variable that contains a pointer to zero or more int.
    • n is a the number of values that a contains.

    You can index a using the standard C++ array access syntax a[i]. Make sure i < n.

    The C++ header would then look like:

    void func(int *a, int n);
    

    The .pyx file would be something like

    cdef extern from "myheader.hpp":
        void func(int *a, int n)
    
    def func_wrapper(int[::1] mview):
        func(&mview[0], mview.shape[0])
    

    You will need to compile it in the usual way being sure to list both your Cython source file and your C source file (the .cpp file, not the header) in the sources list.