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

81,792

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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

Solution 5

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

}
Share:
81,792

Related videos on Youtube

SamuraiT
Author by

SamuraiT

I am still in college, and seek being Pythonista. Programming Experience Includes: Python, Java, C#, javascript, C, C++, R About me Twitter

Updated on July 09, 2022

Comments

  • SamuraiT
    SamuraiT almost 2 years

    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],
    )
    
    • Martijn Pieters
      Martijn Pieters almost 10 years
      That's nowhere near a suitable Python extension module.
    • Martijn Pieters
      Martijn Pieters almost 10 years
      I suggest you first read the C-API tutorial.
    • Cuadue
      Cuadue over 8 years
      For posterity, if you have two files fizzbuzz.so and a (properly written ctypes wrapper) fizzbuzz.py in the same directory, and you try to import fizzbuzz, Python seems to prefer the .so, which also produces this error message.
    • benjimin
      benjimin almost 5 years
      Porting C extensions from python 2 to 3: docs.python.org/3/howto/cporting.html
  • sage
    sage over 8 years
    Wow! This little snippet has been more helpful than most of the Boost docs for me!
  • user2284570
    user2284570 almost 8 years
    −1import _fizzbuzzyieldsdynamic module not initialised properly wheninitfizzbuzzis corrected withinit_fizzbuzz.
  • Martijn Pieters
    Martijn Pieters over 7 years
    Where does the libemotion name come from?
  • Fred Schoen
    Fred Schoen almost 7 years
    initfizzbuzz is the python2 naming scheme, python3 needs PyInit_libfizzbuzz. So if you know your library is built for python3 and you get the error msg. in in the original question, probably some python2 interpreter got into the way. That's what happened to me with a conda env. with python 3.6 and a system python2.7 when building documentation for my module with sphinx.
  • Carlos Ost
    Carlos Ost about 5 years
    That was my case too. I have compiled the python wrapper using python3.6 and was trying to import my lib using python2.7. Thank you for this comment!
  • Wuschelbeutel Kartoffelhuhn
    Wuschelbeutel Kartoffelhuhn almost 4 years
    I had the same issue as OP and your answer worked for me.