ImportError: dynamic module does not define init function (initfizzbuzz)

Question:

I tried to compile fizzbuzz.c, in order to import it by python. For building fizzbuzz.c,I used python setup.py build_ext -i.

After building it, I tried to import fizzbuzz.c but the error below occurred.
How can I solve this problem ?

Error

>>> import fizzbuzz
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initfizzbuzz)

fizzbuzz.c

#include <stdio.h>

void fizzbuzz(int n){

    for (int i=1; i <= n; i++){
        if (i % 3 == 0 && i % 5 ==0){
            printf("fizzbuzz %d n", i);
        }
        else if (i % 3 == 0){
            printf("fizz %d n", i);
        }
        else if(i % 5 == 0){
            printf("buzz %d n", i);
        }
    }
}

setup.py

from distutils.core import setup, Extension
module = Extension('fizzbuzz', ['fizzbuzz.c'])
setup(
      name='fizzbuzz',
      version='1.0',
      ext_modules=[module],
)
Asked By: SamuraiT

||

Answers:

Python doesn’t and cannot support arbitrary C files as modules. You’ll have to follow certain conventions to let Python know what functions your module supports.

To do so, Python will look for a init<name> function, where <name> is the module name. Python was looking for initfizzbuzz but failed to find it, so loading the module failed.

Apart from an initialiser, you also need to provide a structure detailing what functions are available, and your function will need to handle Python types as arguments. Python provides you with the necessary utility functions and defines to make that easy enough.

I strongly urge you follow the Extending and Embedding the Python Interpreter tutorial. It teaches you everything you need to know to make your fizzbuzz C code work as a Python module.

Answered By: Martijn Pieters

You should define a function named init_fizzbuzz, that should contain the code to initialize the module. This function should also call Py_InitModule, to setup the bindings for the c functions in Python. For further info, check out this tutorial.

In yor case, your code should be adapted to something like this:

static PyObject* py_fizzbuzz(PyObject* self, PyObject* args)
{
    int value;
    if (!PyArg_ParseTuple(args, "i", &value))
        return NULL;
    for (int i=1; i <= n; i++){
        if (i % 3 == 0 && i % 5 ==0){
            printf("fizzbuzz %d n", i);
            }
        else if (i % 3 == 0){
            printf("fizz %d n", i);
            }
        else if(i % 5 == 0){
            printf("buzz %d n", i);
            }
        }

    // Return value.
    return Py_BuildValue("i", 0);

}

// Mapping between python and c function names. 
static PyMethodDef fizzbuzzModule_methods[] = {
    {"fizzbuzz", py_fizzbuzz, METH_VARARGS},
    {NULL, NULL}
    };

// Module initialisation routine.
void init_fizzbuzz(void)
{
    // Init module.
    (void) Py_InitModule("fizzbuzz", fizzbuzzModule_methods);

}
Answered By: lackadaisical

The error also occurs, when using boost::python, if the module name is different to the compiled .so file name. For example:

hello.cpp

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace std;
using namespace boost::python;

int helloWorld(){
    cout << "Hello world!" << endl;
    return 0;
}

BOOST_PYTHON_MODULE(libhello) {
    def("hello_world", helloWorld);
}

compilation command:

g++ -fpic -shared -o libfoo.so -Wl,-soname,"libfoo.so" hello.cpp -I<path/to/python> -L/usr/local/lib  -lboost_python-py34

When including in python with import libfoo the following error occurs:

ImportError: dynamic module does not define init function (PyInit_libfoo)

This is because of “libhello” and “libfoo” do not match.

Answered By: philosopher

Worth notify – same error can occur if library is compiled for different python version. For example, if shared object is for python 3, but you try to import module from python 2.

Answered By: Ivan Klass

If you use python 3 then you need to have the following changes on your code,

static struct PyModuleDef fizzbuzzModuleDef =
{
    PyModuleDef_HEAD_INIT,
    "fizzbuzz", /* name of module */
    "",          /* module documentation, may be NULL */
    -1,          /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
    fizzbuzzModule_methods
};

PyMODINIT_FUNC PyInit_exmod(void) {
    return PyModule_Create(&fizzbuzzModuleDef);
}
Answered By: kar

do python3 ./yourpythonscript

instead of

python ./yourpythonscript

even if you have python aliased as python3

The name must be exact with which you compile boost and boost-python:
brew reinstall boost –with-python3 –without-python
brew reinstall boost-python –with-python3 –without-python

Answered By: Aditya Mittal
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.