2011-11-07 6 views
6

Estoy usando Cython (0.15.2) para crear una extensión para Python (2.6.5). Creé un archivo pxd y un archivo pyx. Aquí es el contenido de mi archivo pyx:Error de compilación de Cython para la función libre (No se puede convertir el argumento del objeto Python para escribir 'FooBar *')

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) 

Si comento a cabo la declaración de definición de función libres (es decir, que no son miembros), el código se compila correctamente y se produce la extensión. Sin embargo, si descomentarla y tratar de compilar el archivo, me sale el siguiente mensaje de error:

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

¿Cuál es la causa de esto, y cómo lo arreglo?

Respuesta

4

Una función definida como cpdef es exigible tanto de Python y C.

Si los argumentos se declaran como tipos de datos C, Cython intentará convertir automáticamente los objetos pasados ​​a la función cuando se llama desde Python. Pero tales conversiones solo son posibles para los tipos numéricos y de cadena; todos los demás tipos generarán un error de tiempo de compilación.

¿Quiso decir exponer esta función a Python? Si no, defínalo con cdef.

De lo contrario, tendrá que crear envoltorios para los tipos de C que desea pasar ay desde Python. Vea el Cython Tutorials para algunos ejemplos de cómo hacer esto.

+0

sí, quiero poder llamar a la función C desde Python; la razón para construir la extensión es poder usar los tipos de datos y las funciones en la biblioteca C, desde Python, así que necesito ser capaz de llamar a la función C desde Python, y pasarle los tipos de datos C (desde Python) –

+0

Incodentally, si uso cdef en lugar de cpdef, el código se compila, pero aparece el siguiente mensaje de advertencia: warning: '__pyx_f_6clib_doSomethingInteresting' definido pero no utilizado. De manera insospechada, cuando trato de usar la función de python, obtengo el error AttributeError: el objeto 'module' no tiene el atributo 'doSomethingInteresting' –

+0

@HomunculusReticulli. Ver mi respuesta actualizada. Básicamente, necesitas crear envoltorios para tus tipos de C. – ekhumoro

Cuestiones relacionadas