2011-11-07 7 views
6

Sto usando Cython (0.15.2) per creare un'estensione per Python (2.6.5). Ho creato un file pxd e un file pyx. Ecco il contenuto del mio file pisside:Errore di compilazione di Cython per la funzione gratuita (Impossibile convertire l'argomento dell'oggetto Python per digitare '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) 

Se io commento la libera affermazione definizione di funzione (vale a dire non membro), il codice viene compilato correttamente e l'estensione viene prodotto. Tuttavia, se rimuovere il commento e cercare di compilare il file, ottengo il seguente messaggio di errore:

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

Qual è la causa di questo, e come posso risolvere il problema?

risposta

4

Una funzione definita come cpdef è richiamabile da entrambi Python e C.

Se gli argomenti sono dichiarati come tipi di dati C, Cython tenterà di convertire automaticamente gli oggetti passati alla funzione quando viene chiamata da Python. Ma tali conversioni sono possibili solo per i tipi numerici e di stringa - tutti gli altri tipi comporteranno un errore in fase di compilazione.

Intendevi esporre questa funzione a Python? In caso contrario, definirlo con cdef.

In caso contrario, sarà necessario creare wrapper per i tipi di C che si desidera passare ae da Python. Vedere lo Cython Tutorials per alcuni esempi su come farlo.

+0

sì, voglio essere in grado di chiamare la funzione C da Python - la ragione per la costruzione dell'estensione è quella di poter usare i tipi di dati e le funzioni nella libreria C, da Python - quindi, ho bisogno di essere in grado di chiamare la funzione C da Python e passargli i tipi di dati C (da Python) –

+0

Incodently, se uso cdef invece di cpdef, il codice viene compilato, ma ottengo il seguente messaggio di avviso: warning: '__pyx_f_6clib_doSomethingInteresting' definito ma non usato. Insolitamente, quando provo ad usare la funzione da python, ottengo l'errore AttributeError: l'oggetto 'module' non ha attributo 'doSomethingInteresting' –

+0

@HomunculusReticulli. Vedi la mia risposta aggiornata. Fondamentalmente, devi creare wrapper per i tuoi tipi C. – ekhumoro

Problemi correlati