10 votes

ImportError : le module dynamique ne définit pas de fonction init, mais il en définit une.

J'essaie d'écrire une liaison pour une bibliothèque C++ d'un fournisseur. J'ai utilisé avec succès des extraits tels que celui ci-dessous pour définir des fonctions init dans les autres modules, mais dans celui-ci, cela ne semble pas fonctionner : il compile bien, mais jette l'ImportError dès que j'essaie de l'importer dans un test script. Qu'est-ce qui peut bien se passer ici ?

#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC initclient(void) {

    PyObject* m;

    ClientType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&ClientType) < 0)
        return;

    m = Py_InitModule3("client", client_methods, "Client module");
    Py_INCREF(&ClientType);
    PyModule_AddObject(m, "Client", (PyObject *) &ClientType);

}

C'est sur Linux 32 bits, avec gcc 4.4.4.

8voto

lin3 Points 81

J'ai eu le même problème. Au moment de la compilation :

  • chemin vers l'en-tête Python : OK
  • chemin d'accès à la bibliothèque Python : OK
  • lien avec la bibliothèque Python : OK
  • établir un lien avec les bibliothèques/fichiers objet de tiers nécessaires : OK

J'ai juste oublié de compiler le fichier C qui définit mon module... Sigh...

Donc oui, première chose à vérifier : votre makefile ou votre commande de compilation ! :)

8voto

Klaas Points 81

Veillez à ne pas mélanger les versions de Python. Dans la version 2 de Python, la fonction init s'appelait Init_, tandis que dans la version 3, cette fonction s'appelle PyInit_.

Dans mon cas, cela se produisait lorsque SWIG 3.0.2 utilisait Python 3.4 pour générer des liaisons, alors que mon IDE Python appelait l'interpréteur Python 2.7.

Vous pouvez voir la différence dans le fichier .cxx généré :

#if PY_VERSION_HEX >= 0x03000000
#  define SWIG_init    PyInit__<modulename>

#else
#  define SWIG_init    init_<modulename>

#endif

Sous Linux, vous pouvez également utiliser la commande suivante pour vérifier vos exportations .so :

nm -D <modulename> | grep <modulename>

Cela vous donnera le nom de la fonction init dans votre bibliothèque.

5voto

dividebyzero Points 408

J'ai eu le même message d'erreur, mais c'est parce que j'ai renommé mon fichier .c, et j'ai oublié de mettre à jour le nom dans le code. La fonction "initxxx" et un argument à l'intérieur.

1voto

Jackie Lee Points 111

Assurez-vous d'inclure votre _wrap.cxx. Il me semble qu'il n'est pas compilé dans votre module.

0voto

demented hedgehog Points 733

Sous linux, il peut être utile d'exécuter strace dans ce cas. Vérifiez que le nom de la bibliothèque que python recherche est le même que celui de la bibliothèque que vous avez construite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X