2010-11-06 16 views
7

Sto provando a scrivere un wrapper python per una funzione C. Dopo aver scritto tutto il codice e averlo compilato, Python non può importare il modulo. Sto seguendo l'esempio dato here. Lo riproduco qui, dopo aver corretto alcuni refusi. C'è un file myModule.c:. Il modulo non importa in python: il modulo dinamico non definisce la funzione 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); 
} 

Dato che io sono su un Mac con MacPorts pitone, compilo come

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

Tuttavia, ottengo un errore quando provo ad importarlo.

$ 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) 

Perché non è possibile importarlo?

+0

Il tuo codice sembra essere un po 'confuso. –

+1

@ Iggacio: sto solo cercando di seguire gli esempi. C'è un esempio più semplice a cui potresti indirizzarmi? – highBandWidth

+0

Il codice nella casella in alto riflette davvero quello che hai nel tuo file sorgente? –

risposta

5

Poiché si utilizza un compilatore C++, i nomi delle funzioni saranno mangled (ad esempio, il mio g++ mangles void initmyModule() in _Z12initmyModulev). Pertanto, l'interprete python non troverà la funzione init del tuo modulo.

È necessario usare sia per un compilatore C pianura, o forzare collegamento C per tutto il modulo con una direttiva 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' come fornita nella documentazione gestirà ciò per te. –

+0

@ IgnacioVazquez-Abrams: Potresti per favore elaborare come eseguire la tua soluzione? Grazie. – RDK

Problemi correlati