ImportError:动态模块没有定义init函数,但确实如此

时间:2011-02-18 13:29:57

标签: c++ python

我正在尝试为供应商C ++库编写绑定。我已成功使用如下所示的片段来定义其他模块中的init函数,但是在这一段中它似乎不起作用:它编译得很好,但是当我尝试将它导入测试时抛出ImportError脚本。这可能有什么问题?

#ifndef PyMODINIT_FUNC  /* declarations for DLL import/export */
#define PyMODINIT_FUNC void
#endif
PyMODINIT_FUNC initclient(void) {

    PyObject* m;

    ClientType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&ClientType) < 0)
        return;

    m = Py_InitModule3("client", client_methods, "Client module");
    Py_INCREF(&ClientType);
    PyModule_AddObject(m, "Client", (PyObject *) &ClientType);

}

这是在32位Linux上,使用gcc 4.4.4。

8 个答案:

答案 0 :(得分:7)

我有同样的问题。在编译时:

  • Python标头的路径:确定
  • Python库的路径:好的
  • 链接Python库:好的
  • 链接所需的第三方库/目标文件:确定

我忘了编译定义模块的C文件......叹息......

所以是的,首先要检查的是:你的makefile或你的编译命令! :)

答案 1 :(得分:7)

确保不要混合使用Python版本。在Python版本2中,init函数称为Init_,而在版本3中,此函数称为PyInit _

在我的情况下,当SWIG 3.0.2使用Python 3.4生成绑定时,就会发生这种情况,而我的Python IDE则称为Python 2.7解释器。

您可以在生成的.cxx文件中看到差异:

#if PY_VERSION_HEX >= 0x03000000
#  define SWIG_init    PyInit__<modulename>

#else
#  define SWIG_init    init_<modulename>

#endif

在Linux上,您还可以使用以下命令检查.so导出:

nm -D <modulename> | grep <modulename>

这将为您提供库中init函数的名称。

答案 2 :(得分:5)

我有相同的错误消息,但这是因为我重命名了我的.c文件,忘记更新代码中的名称。 “initxxx”函数及其中的参数。

答案 3 :(得分:1)

确保包含_wrap.cxx。在我看来它不会被编译到你的模块中。

答案 4 :(得分:0)

在Linux上,在这种情况下可以帮助运行strace。检查库python的名称是否与您构建的库的名称相同。

答案 5 :(得分:0)

swig文档提到了here

  

当给共享对象文件指定错误名称时,几乎总是会导致此错误。例如,如果您创建了一个文件example.so而不是_example.so,则会出现此错误。

答案 6 :(得分:0)

在界面文件中,SWIG建议使用:

#define SWIG_FILE_WITH_INIT

答案 7 :(得分:-3)

这与Python或编译器无关,但编译器咒语不正确(编辑Makefile时需要多加注意)。