2010-11-06 26 views
7

Tôi đang cố gắng để viết một wrapper python cho một chức năng C. Sau khi viết tất cả các mã, và làm cho nó biên dịch, Python không thể nhập mô-đun. Tôi đang làm theo ví dụ được đưa ra here. Tôi tái tạo nó ở đây, sau khi sửa một số lỗi chính tả. Có một myModule.c file:.so mô-đun không nhập khẩu trong python: mô-đun năng động không xác định chức năng 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); 
} 

Kể từ khi tôi đang trên một máy Mac với Macports python, tôi biên dịch nó như

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

Tuy nhiên, tôi nhận được một lỗi khi tôi cố gắng để import nó.

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

Tại sao tôi không thể nhập?

+0

Mã của bạn có vẻ là một chút bị cắt xén. –

+1

@Ignacio: Tôi chỉ đang cố gắng làm theo các ví dụ. Có một ví dụ đơn giản hơn bạn có thể chỉ cho tôi? – highBandWidth

+0

Mã trong hộp trên cùng có phản ánh những gì bạn có trong tệp nguồn không? –

Trả lời

5

Vì bạn đang sử dụng trình biên dịch C++, tên hàm sẽ là mangled (ví dụ: g++ mangles void initmyModule() thành _Z12initmyModulev). Do đó, trình thông dịch python sẽ không tìm thấy hàm init của module của bạn.

Bạn cần phải hoặc sử dụng một trình biên dịch C đơn giản, hoặc buộc C liên kết xuyên suốt mô-đun của bạn với một chỉ thị 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

Macro 'PyMODINIT_FUNC' như được đưa ra trong tài liệu sẽ xử lý việc này cho bạn. –

+0

@ IgnacioVazquez-Abrams: Bạn có thể giải thích cách thực hiện giải pháp của mình không? Cảm ơn. – RDK

Các vấn đề liên quan