ImportError: динамический модуль не определяет функцию init (initfizzbuzz)

Я попытался скомпилировать fizzbuzz.c для импорта из python. Для строительства fizzbuzz.cpython setup.py build_ext -i.

после его создания я попытался импортировать fizzbuzz.c но произошла ошибка ниже. Как я могу решить эту проблему ?

>>> 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],
)

6 ответов


Python не поддерживает и не может поддерживать произвольные файлы C в качестве модулей. Вы должны будете следовать определенным соглашениям, чтобы Python знал, какие функции поддерживает ваш модуль.

для этого Python будет искать , где <name> - имя модуля. Питон засмотрелся на initfizzbuzz, но не удалось найти его, поэтому загрузка модуля не удалось.

отдельно от инициализатора, вам также нужно обеспечить структуру детализируя какие функции доступны, и Ваше функция должна будет обрабатывать типы Python в качестве аргументов. Python предоставляет вам необходимые функции утилиты и определяет, чтобы сделать это достаточно простым.

я настоятельно призываю вас следовать расширение и внедрение учебника интерпретатора Python. Он учит вас всему, что вам нужно знать, чтобы сделать ваш fizzbuzz код C работает как модуль Python.


ошибка также возникает, при использовании boost:: python, если имя модуля отличается от скомпилированного .Итак, имя файла. Например:

Здравствуйте.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);
}

команды компиляции:

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

когда в том числе и в python С import libfoo возникает следующая ошибка:

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

это из-за того, что" libhello "и" libfoo " не совпадают.


Worth notify-такая же ошибка может произойти, если библиотека скомпилирована для другой версии python. Например, если общий объект предназначен для python 3, но вы пытаетесь импортировать модуль из python 2.


вы должны определить функцию с именем init_fizzbuzz, который должен содержать код инициализации модуля. Эта функция также должна вызывать Py_InitModule, чтобы настроить привязки для функций c в Python. Для получения дополнительной информации, проверьте в этом уроке.

в вашем случае ваш код должен быть адаптирован к чему-то вроде этого:

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

}

Если вы используете python 3, вам нужно внести следующие изменения в свой код,

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

do python3 ./ yourpythonscript

вместо

python ./ yourpythonscript

даже если у вас есть Python с псевдонимами python3

имя должно быть точным, с помощью которого вы компилируете boost и boost-python: заварить переустановить boost --with-python3 --without-python заварить переустановить boost-python --with-python3 --without-python