web-dev-qa-db-fra.com

Extension C compilée par Cython: ImportError: le module dynamique ne définit pas la fonction init

Je viens de compiler une partie de ma bibliothèque C en tant qu'extension utilisant Cython, comme "preuve de concept". J'ai réussi à pirater le code (problèmes de correction const, etc. de côté), pour finalement obtenir une extension construite.

Cependant, lorsque j'ai tenté d'importer l'extension nouvellement créée, j'ai eu l'erreur suivante:

ImportError: dynamic module does not define init function 

Qu'est-ce que je fais mal et comment puis-je résoudre ce problème?

J'utilise Cythn 0.11.2 et Python 2.6.5 sur Ubuntu 10.0.4

39

J'ai constaté qu'une cause fréquente de ce problème est que, lorsque vous utilisez un fichier d'installation distutils pour compiler le code, le nom de base .pyx ne correspond pas au nom d'extension, par exemple:

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

Pour éviter le problème, le nom de l'extension doit être exactement le même, dans ce cas, cython_ext.

63
Dologan

Il semble que ce soit un bogue/une fonctionnalité de Cython. J'ai eu la même chose, mais j'ai simplement ajouté:

STUFF = "Hi"

au sommet de mon fichier .pyx et le problème a disparu. En l'absence d'initialisation globale (cinit ou en définissant une variable globale), il semble que le code d'initialisation requis ne soit pas généré.

20
Tim

C'est une réponse très tardive - mais j'ai juste eu la même erreur, et la mienne est partie quand j'ai utilisé __cinit__ au lieu de __init__. Je suis encore en train d'apprendre sur les types d'extension, donc pour l'instant je ne sais pas pourquoi cela se produit. :) (Vous pouvez jeter un oeil à http://docs.cython.org/src/reference/extension_types.html#initialization-cinit-and-init ) J'espère que cela sera utile à quelqu'un.

3
joon

J'apprends actuellement Cython avec le livre O'Reilly et je suis confronté au même problème. Ce qui a résolu le problème pour moi, c’est d’ajouter une chaîne de caractères à la fonction.

Cela n'a pas fonctionné:

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

Cela a fonctionné:

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
0
GetLastError

J'ai eu la même erreur et a été résolu en exécutant le script principal .py en mode "Exécuter dans une console dédiée". Disponible dans Outils - Préférences - Exécuter.

0
aishwarya selvaraj

Autre réponse très tardive dans mon cas, j’ai accidentellement appelé cython dans un terminal qui exécutait python2, alors que j’essayais d’utiliser la bibliothèque générée à partir d’un terminal se trouvant dans un autre environnement python, à l’aide de python3.

Utiliser la même version python partout l'a corrigé.

0
Cola_Colin

De même, une réponse tardive ... mais je n'arrêtais pas de revenir à cette question en particulier. Cela est probablement lié à la question des noms incompatibles abordés par Dologan.

Ce qui s’est passé dans mon cas, c’est que j’étais en train d’adapter un exemple et que j’avais eu l’erreur module does not define init function. Ceci a été vérifié en utilisant (par exemple)

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

Dans la sortie de cette commande, j'ai recherché 'init' et trouvé

000000000000c0d0 (__TEXT, __ text) external _initexample

J'avais supprimé toutes les instances de 'exemple' de mes fichiers setup.py et .pyx, mais cela persistait même après la suppression de l'extension de site-packages, la suppression des dossiers build et dist, etc. J'ai finalement trouvé que le fichier .cpp était généré à partir de. Le fichier pyx faisait toujours référence au nom de la classe dans l'exemple. Une fois que j’ai relancé mon setup.py, l’importation fonctionne et le fichier .so contient

000000000000c0a0 (__TEXT, __ text) external _initmyproj

0
Gertlex