2010-11-06 19 views
7

Próbuję napisać wrapper Pythona dla funkcji C. Po napisaniu całego kodu i skompilowaniu go Python nie może zaimportować modułu. Podążam za przykładem podanym here. Powtarzam to tutaj, po naprawieniu niektórych literówek. Jest myModule.c file:.so moduł nie importuje w python: moduł dynamiczny nie definiuje funkcji 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); 
} 

Ponieważ jestem na Mac DarwinPorts pytona, skompilować go jako

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

Jednakże pojawia się błąd, gdy próbuję go importować.

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

Dlaczego nie mogę go zaimportować?

+0

Kod wydaje się być nieco zniekształcone. –

+1

@Ignacio: Próbuję tylko podążać za przykładami. Czy istnieje prostszy przykład, na który możesz mnie wskazać? – highBandWidth

+0

Czy kod w górnym polu rzeczywiście odzwierciedla to, co masz w pliku źródłowym? –

Odpowiedz

5

Ponieważ używasz kompilatora C++, nazwy funkcji będzie mangled (na przykład, mój g++ Zmieniany void initmyModule() do _Z12initmyModulev). Dlatego też interpreter python nie znajdzie funkcji inicjującej twojego modułu.

trzeba użyć zwykłego kompilatora C lub C wymusić łączenie całej modułu z dyrektywą 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

Makro "PyMODINIT_FUNC" podane w dokumentacji obsłuży to za Ciebie. –

+0

@ Ignacio Vaazquez-Abrams: Czy mógłbyś wyjaśnić, jak przeprowadzić swoje rozwiązanie? Dzięki. – RDK

Powiązane problemy