Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cython compilation error for free function (Cannot convert Python object argument to type 'FooBar *')

I am using Cython (0.15.2) to create an extension for Python (2.6.5). I have created a pxd file and a pyx file. Here are the contents of my pyx file:

cimport capifuncs

cdef class myArray:
    cdef capifuncs.myArray *_my_array
    def __cinit__(self, size):
        self._my_array = capifuncs.array_new(size)
        if (self._my_array is NULL):
            raise MemoryError()

    def __dealloc__(self):
        if self._my_array is not NULL:
            capifuncs.array_free(self._my_array)

    def __bool__(self):
        return not capifuncs.IsEmpty(self._my_array)


    ##############################
    #        Array methods       #
    ##############################

    cpdef getItem(self, unsigned int pos):
        if capifuncs.IsEmpty(self._my_array):
            raise IndexError("Array is empty")
        #if ():
        #    raise IndexError("Array bounds exceeded")

        return capifuncs.array_get_item(self._my_array, pos)


    cpdef setItem(self, unsigned int pos, double val):
        if capifuncs.IsEmpty(self._my_array):
            raise IndexError("Array is empty")
        #if ():
        #    raise IndexError("Array bounds exceeded")

        capifuncs.array_set_item(self._my_array, pos, val)




# Free functions
cpdef long someCAPIFuncCall(capifuncs.FooBar *fb, capifuncs.myArray *arr, long start, long stop):
    return capifuncs.doSomethingInteresting(fb, arr, start, stop)

If I comment out the free (i.e. non-member) function definition statement, the code compiles correctly and the extension is produced. However, if I uncomment it and try to compile the file, I get the following error message:

cafuncs.pyx:64:23: Cannot convert Python object argument to type 'FooBar *'

What is the cause of this, and how do I fix it?

like image 908
Homunculus Reticulli Avatar asked Nov 07 '11 17:11

Homunculus Reticulli


1 Answers

A function defined as cpdef is callable from both Python and C.

If the arguments are declared as C data types, Cython will attempt to automatically convert the objects passed into the function when it's called from Python. But such conversions are only possible for numeric and string types - all other types will result in a compile-time error.

Did you mean to expose this function to Python? If not, define it with cdef.

Otherwise, you will need to create wrappers for the C types that you want to pass to and from Python. See the Cython Tutorials for some examples of how to do this.

like image 182
ekhumoro Avatar answered Sep 25 '22 14:09

ekhumoro