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

1

7

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?

Presumable answered 7/11, 2011 at 17:55 Comment(0)
T
4

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.

Tent answered 7/11, 2011 at 19:31 Comment(7)
yes, I want to be able to call the C function from Python - the reason for building the extension is to be able to use the data types and functions in the C library, from Python - so, I do need to be able to call the C function from Python, and pass it the C data types (from Python)Presumable
Incodentally, if I use cdef instead of cpdef, the code compiles, but I get the following warning message : warning: ‘__pyx_f_6clib_doSomethingInteresting’ defined but not used. Unsuprisingly, when I try to use the function from python, I get the error AttributeError: 'module' object has no attribute 'doSomethingInteresting'Presumable
@HomunculusReticulli. See my updated answer. Basically, you need to create wrappers for your C types.Tent
I have already created wrappers for my C types - granted I did not show the cdef class for FooBar in the snippet in my question (for brevity sake).Presumable
The problem with the examples in the link is that they only show how to implement object methods - they don't show how to call free (non-member) functions taht accept C data types as arguments.Presumable
@HomunculusReticulli. Have you tried someCAPIFuncCall(capifuncs.FooBar fb, capifuncs.myArray arr, ...?Tent
Yes that was what the original code was like, but I got compilation errors (I can't remember the message). As an aside, whilst I was waiting for an answer to this question, I decided to switch to SWIG. I have since built the module successfully (using SWIG) and am now testing it.Presumable

© 2022 - 2024 — McMap. All rights reserved.