1

I want to use the data from an c array in cython/python code.

To do so I tried to convert the c array with numpy.ctypeslib.ndpointer.
I get the error Cannot convert 'float *' to Python object.

Below is a simple example I tried to get up and running for a couple of days now.

Lets say we have a c function that creates an array. c_code.c

float *compute(int size)
{
    float* array;
    array = malloc(sizeof(float)*size);
    int i;
    for (i=0; i<size; i++)
    {
       array[i] = i;
    }
    return array;
}

In cython I have cython_wrapper.pyx:

# Declare the prototype of the C function we are interested in calling
cdef extern from "c_code.c":
    float*compute(int size)

# Import the Python-level symbols of numpy
import numpy as np

# Import the C-level symbols of numpy
cimport numpy as np
import ctypes

# Numpy must be initialized. When using numpy from C or Cython you must
# _always_ do that, or you will have segfaults
np.import_array()

def py_compute(int size):
    """ Python binding of the 'compute' function in 'c_code.c' that does
        not copy the data allocated in C.
    """
    cdef float *array
    cdef np.ndarray ndarray
    # Call the C function
    array = compute(size)

    func = np.ctypeslib.ndpointer(dtype=ctypes.c_int, shape=(size,))
    ndarray = func(array)
    return ndarray

setup.py:

import numpy
from Cython.Distutils import build_ext


def configuration(parent_package='', top_path=None):
    """ Function used to build our configuration.
    """
    from numpy.distutils.misc_util import Configuration

    # The configuration object that hold information on all the files
    # to be built.
    config = Configuration('', parent_package, top_path)
    config.add_extension('cython_wrapper',
                         sources=['cython_wrapper.pyx'],
                         # libraries=['m'],
                         depends=['c_code.c'],
                         include_dirs=[numpy.get_include()])
    return config


if __name__ == '__main__':
    # Retrieve the parameters of our local configuration
    params = configuration(top_path='').todict()

    # Override the C-extension building so that it knows about '.pyx'
    # Cython files
    params['cmdclass'] = dict(build_ext=build_ext)

    # Call the actual building/packaging function (see distutils docs)
    from numpy.distutils.core import setup

    setup(**params)
9
  • 1
    While your question isn't a duplicate of stackoverflow.com/questions/23872946/…, I think the answers there will be what you want. Commented Oct 13, 2015 at 17:17
  • 1
    I think ctypes isn't the right approach (and in any case you're misunderstanding ndpointer, which is for declaring function interfaces). Commented Oct 13, 2015 at 17:18
  • 1
    You could also look at docs.cython.org/src/userguide/memoryviews.html#cython-arrays for a different approach to the same problem, but if you want a numpy array you'll probably find the first link more helpful. Commented Oct 13, 2015 at 17:20
  • 1
    If that's your main requirement I think the cython array/memoryview approach (in my third comment) is probably the easiest option. Commented Oct 13, 2015 at 21:07
  • 1
    Good. 2 things: 1) It's more useful to answer yourv own question than edit the answer into the question. 2) Think about how the memory gets freed? I don't think it does in the very simple version you have there... Commented Oct 14, 2015 at 14:08

1 Answer 1

2

@DavidW pointed you that numpy.ctypeslib.ndpointer is not the right way to go for what I want to do.

Basically I just want to convert an c-array to an cython/python-array.

With help of this link I found the answer: http://docs.cython.org/src/userguide/memoryviews.html#cython-arrays

def py_compute(int size):
    return <float[:size]> (compute(size))

I'm freeing the memory in c so that I dont have to worry about freeing it in python and therefor can use this really simple solution.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.