2010-11-06 17 views
7

J'essaye d'écrire un wrapper python pour une fonction C. Après avoir écrit tout le code et l'avoir compilé, Python ne peut pas importer le module. Je suis l'exemple donné here. Je le reproduis ici, après avoir corrigé quelques fautes de frappe. Il y a un fichier myModule.c:.so le module ne pas importer en python: le module dynamique ne définit pas la fonction init

#include <Python.h> 

/* 
* Function to be called from Python 
*/ 
static PyObject* py_myFunction(PyObject* self, PyObject* args) 
{ 
    char *s = "Hello from C!"; 
    return Py_BuildValue("s", s); 
} 
/* 
* Bind Python function names to our C functions 
*/ 
static PyMethodDef myModule_methods[] = { 
    {"myFunction", py_myFunction, METH_VARARGS}, 
    {NULL, NULL} 
}; 

/* 
* Python calls this to let us initialize our module 
*/ 
void initmyModule() 
{ 
    (void) Py_InitModule("myModule", myModule_methods); 
} 

Depuis que je suis sur un python Mac avec Macports, je compile comme

$ g++ -dynamiclib -I/opt/local/Library/Frameworks/Python.framework/Headers -lpython2.6 -o myModule.dylib myModule.c 
$ mv myModule.dylib myModule.so 

Cependant, je reçois une erreur lorsque je tente d'importer.

$ ipython 
In[1]: import myModule 
--------------------------------------------------------------------------- 
ImportError        Traceback (most recent call last) 

/Users/.../blahblah/.../<ipython console> in <module>() 

ImportError: dynamic module does not define init function (initmyModule) 

Pourquoi ne puis-je pas l'importer?

+0

Votre code semble être un peu confus. –

+1

@Ignacio: J'essaie juste de suivre les exemples. Y a-t-il un exemple plus simple que vous pourriez me montrer? – highBandWidth

+0

Est-ce que le code dans la case supérieure reflète vraiment ce que vous avez dans votre fichier source? –

Répondre

5

Puisque vous utilisez un compilateur C++, les noms de fonctions seront mangled (par exemple, mon g++ Mangles void initmyModule() en _Z12initmyModulev). Par conséquent, l'interpréteur python ne trouvera pas la fonction init de votre module.

Vous devez soit utiliser un compilateur C ordinaire ou forcer liaison C tout au long de votre module avec une directive extern "C":

#ifdef __cplusplus 
extern "C" { 
#endif 

#include <Python.h> 

/* 
* Function to be called from Python 
*/ 
static PyObject* py_myFunction(PyObject* self, PyObject* args) 
{ 
    char *s = "Hello from C!"; 
    return Py_BuildValue("s", s); 
} 

/* 
* Bind Python function names to our C functions 
*/ 
static PyMethodDef myModule_methods[] = { 
    {"myFunction", py_myFunction, METH_VARARGS}, 
    {NULL, NULL} 
}; 

/* 
* Python calls this to let us initialize our module 
*/ 
void initmyModule() 
{ 
    (void) Py_InitModule("myModule", myModule_methods); 
} 

#ifdef __cplusplus 
} // extern "C" 
#endif 
+2

La macro 'PyMODINIT_FUNC' telle que donnée dans la documentation va gérer cela pour vous. –

+0

@ IgnacioVazquez-Abrams: Pourriez-vous s'il vous plaît élaborer comment réaliser votre solution? Merci. – RDK