2010-11-06 20 views
7

Estoy tratando de escribir un wrapper python para una función C. Después de escribir todo el código y hacer que compile, Python no puede importar el módulo. Estoy siguiendo el ejemplo dado here. Lo reproduzco aquí, después de corregir algunos errores tipográficos. Hay una myModule.c archivo:.so module doesnt import in python: el módulo dinámico no define la función 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); 
} 

Desde que estoy en una pitón Mac con MacPorts, compilo como

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

Sin embargo, me da un error al intentar 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) 

¿Por qué no puedo importarlo?

+0

Su código parece ser un poco confuso. –

+1

@Ignacio: Solo trato de seguir los ejemplos. ¿Hay algún ejemplo más simple al que me puedas dirigir? – highBandWidth

+0

¿El código en el cuadro superior realmente refleja lo que tienes en tu archivo fuente? –

Respuesta

5

Dado que está utilizando un compilador de C++, nombres de función serán mangled (por ejemplo, mi g++ Mangles void initmyModule() en _Z12initmyModulev). Por lo tanto, el intérprete de Python no encontrará la función init de su módulo.

Necesitas utilizar un compilador de C llana, o forzar la vinculación C a través de su módulo con una directiva 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' tal como figura en la documentación se encargará de esto. –

+0

@ IgnacioVazquez-Abrams: ¿Podría explicar cómo llevar a cabo su solución? Gracias. – RDK

Cuestiones relacionadas