2011-11-06 8 views
37

Ho appena compilato parte della mia libreria C come un'estensione usando Cython, come una "prova di concetto". Sono riuscito a hackerare il codice (const problemi risolti ecc. A parte), per ottenere finalmente un'estensione costruita.Estensione C compilata da Cython: ImportError: il modulo dinamico non definisce la funzione init

Tuttavia, quando ho tentato di importare l'estensione appena creata, ho ricevuto il seguente errore:

ImportError: dynamic module does not define init function 

Che cosa sto facendo di sbagliato e come posso risolvere questo problema?

Sto usando Cythn 0.11.2 e Python 2.6.5 su Ubuntu 10.0.4

+1

Che riga di comando hai usato per generare il .c? Come lo hai compilato? – tito

+0

Non ho ancora ricevuto risposta su una [domanda Cython] (http://stackoverflow.com/questions/41926482/cython-compileerror-when-attempting-to-compile-extension-type) riguardante un errore di compilazione. Potresti essere in grado di aiutarti. – Phillip

risposta

56

Ho scoperto che una causa frequente di questo problema è, quando si utilizza un file di installazione distutils per compilare il codice, che il nome di base .pyx non corrisponde al nome di estensione, ad esempio:

ext = Extension(name='different', sources=['cython_ext.pyx']) # Won't work 

Per evitare il problema, il nome dell'interno dovrebbe essere esattamente lo stesso, in questo caso, cython_ext.

+0

Bella chiamata. Qualcuno sa perché questo funziona, e perché un altro nome non lo fa? – dinkelk

+0

Non ho ancora ricevuto risposta su una [domanda Cython] (http://stackoverflow.com/questions/41926482/cython-compileerror-when-attempting-to-compile-extension-type) riguardante un errore di compilazione. Potresti essere in grado di aiutarti. – Phillip

+0

@dologan, grazie mille per avermi salvato un giorno! – q0987

3

Questa è una risposta molto tardi - ma ho appena avuto lo stesso errore, e la mia è andato via quando ho usato __cinit__ invece di __init__. Sono ancora interessato ai tipi di estensione, quindi attualmente non so perché questo accada. :) (Puoi dare un'occhiata a http://docs.cython.org/src/reference/extension_types.html#initialization-cinit-and-init) Spero che questo sia utile a qualcuno.

+0

Non ho ancora ricevuto risposta su una [domanda Cython] (http://stackoverflow.com/questions/41926482/cython-compileerror-when-attempting-to-compile-extension-type) riguardante un errore di compilazione. Potresti essere in grado di aiutarti. – Phillip

16

Sembra che sia un bug/funzionalità in Cython. Ho avuto la stessa cosa, ma semplicemente aggiunto:

STUFF = "Hi" 

alla parte superiore del mio file .pyx e la questione è andato via. Appare se non vi è un'inizializzazione globale (a cinit o l'impostazione di una variabile globale), che il codice di inizializzazione richiesto non viene generato.

+3

Wow. Non posso credere che abbia funzionato, ma ha risolto lo stesso bug nella mia libreria. – Rick

+0

Questo ha funzionato anche per me .. Per la mia incredulità. – coffeepls

0

Allo stesso modo una risposta tardiva ... ma ho continuato a trovare la strada per tornare a questa domanda in particolare. Probabilmente è legato al problema dei nomi non corrispondenti che Dologan affronta.

Quello che è successo nel mio caso è stato che stavo adattando un esempio che avevo ottenuto per lavorare e ho ricevuto l'errore module does not define init function. Questo è stato verificato utilizzando (per esempio)

nm -m build/lib.macosx-10.9-x86_64-2.7/myproj.so

In uscita di questo comando ho cercato per 'init' e ho trovato

000000000000c0d0 (__TEXT,__text) external _initexample

avevo rimosso tutte le istanze di 'esempio' dal mio file setup.py e .pyx , ma questo persisteva anche dopo aver rimosso l'estensione da site-packages, rimuovendo le cartelle build e dist, ecc. Alla fine ho scoperto che il file .cpp generato dal mio file .pyx faceva ancora riferimento al nome della classe nell'esempio. Una volta ho reran mie opere setup.py, di importazione, e in effetti il ​​file .so include

000000000000c0a0 (__TEXT,__text) external _initmyproj

0

Attualmente sto imparando Cython con il libro O'Reilly, e di fronte lo stesso problema. Quello che mi ha risolto il problema era aggiungere una docstring alla funzione.

Questo non ha funzionato:

def fib(int n): 
    cdef int i 
    cdef double a=0.0, b=1.0 
    for i in range(n): 
     a, b = a + b, a 
    return a 

questo ha funzionato:

def fib(int n): 
    '''Returns the nth Fibonacci number.''' 
    cdef int i 
    cdef double a=0.0, b=1.0 
    for i in range(n): 
     a, b = a + b, a 
    return a