ImportError:动态模块没有定义init函数(initfizzbuzz)

Sam*_*aiT 36 c python python-c-extension

我试图编译fizzbuzz.c从python导入.对于建筑fizzbuzz.c,我用过python 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)
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

setup.py

from distutils.core import setup, Extension
module = Extension('fizzbuzz', ['fizzbuzz.c'])
setup(
      name='fizzbuzz',
      version='1.0',
      ext_modules=[module],
)
Run Code Online (Sandbox Code Playgroud)

phi*_*her 56

如果模块名称与编译的.so文件名不同,则在使用boost :: python时也会发生错误.例如:

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);
}
Run Code Online (Sandbox Code Playgroud)

编译命令:

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

包括当蟒蛇import libfoo出现以下错误:

ImportError: dynamic module does not define init function (PyInit_libfoo)
Run Code Online (Sandbox Code Playgroud)

这是因为"libhello"和"libfoo"不匹配.

  • 哇!这个小片段对我来说比大多数Boost文档更有帮助! (13认同)

Iva*_*ass 29

值得通知 - 如果为不同的python版本编译库,可能会发生同样的错误.例如,如果共享对象是用于python 3,但是您尝试从python 2导入模块.

  • `initfizzbuzz`是python2命名方案,python3需要`PyInit_libfizzbuzz`.因此,如果您知道您的库是为python3构建的,那么您将收到错误消息.在最初的问题中,可能有一些python2解释器遇到了问题.这就是我用conda env发生的事情.使用spthonx为我的模块构建文档时使用python 3.6和系统python2.7. (5认同)

Mar*_*ers 21

Python没有也不能支持任意C文件作为模块.您必须遵循某些约定才能让Python知道您的模块支持哪些功能.

为此,Python将寻找一个init<name>函数,<name>模块名称在哪里.Python正在寻找initfizzbuzz但未能找到它,因此加载模块失败了.

除了初始化之外,您还需要提供一个详细说明可用函数的结构,并且您的函数需要将Python类型作为参数处理.Python为您提供了必要的实用程序功能,并定义了使其足够简单.

我强烈建议您按照扩展和嵌入Python解释器教程进行操作.它教你了解fizzbuzzC代码作为Python模块所需要知道的一切.


Adi*_*tal 6

做 python3 ./yourpythonscript

代替

蟒蛇./你的pythonscript

即使你将 python 别名为 python3

名称必须与您编译 boost 和 boost-python 的名称完全相同: brew restart boost --with-python3 --without-python brew restart boost-python --with-python3 --without-python


lac*_*cal 5

您应该定义一个名为的函数init_fizzbuzz,该函数应包含初始化模块的代码.此函数还应调用Py_InitModule,以在Python中设置c函数的绑定.有关详细信息,请查看本教程.

在你的情况下,你的代码应该适应这样的事情:

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

}
Run Code Online (Sandbox Code Playgroud)