8

I am trying to write a python wrapper for a C function. After writing all the code, and getting it to compile, Python can't import the module. I am following the example given here. I reproduce it here, after fixing some typos. There is a file myModule.c:

#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);
}

Since I am on a Mac with Macports python, I compile it as

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

However, I get an error when I try to import it.

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

Why can't I import it?

4
  • Your code seems to be a bit garbled. Commented Nov 6, 2010 at 7:53
  • 1
    @Ignacio: I am just trying to follow the examples. Is there a simpler example you could point me to? Commented Nov 6, 2010 at 7:55
  • Does the code in the top box really reflect what you have in your source file? Commented Nov 6, 2010 at 7:56
  • @Ignacio. Sorry, you're right. It messed up when I copied it from the file. I recopied the code. It now reflects what I have in my source file. Commented Nov 6, 2010 at 8:00

1 Answer 1

5

Since you're using a C++ compiler, function names will be mangled (for instance, my g++ mangles void initmyModule() into _Z12initmyModulev). Therefore, the python interpreter won't find your module's init function.

You need to either use a plain C compiler, or force C linkage throughout your module with an extern "C" directive:

#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 
Sign up to request clarification or add additional context in comments.

2 Comments

The PyMODINIT_FUNC macro as given in the documentation will handle this for you.
@IgnacioVazquez-Abrams: Could you please elaborate how to carry out your solution? Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.