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

djc*_*djc 9 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);

}
Run Code Online (Sandbox Code Playgroud)

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

小智 8

我遇到过同样的问题.在编译时:

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

我只是忘了编译定义我的模块的C文件......叹气......

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


小智 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
Run Code Online (Sandbox Code Playgroud)

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

nm -D <modulename> | grep <modulename>
Run Code Online (Sandbox Code Playgroud)

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


div*_*ero 5

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


djc*_*djc -3

这与Python或编译器无关,而是一个不正确的编译器咒语(在编辑Makefile时必须多加注意)。

  • 如果您能为其他有同样问题的人提供您的解决方案,那就太好了! (24认同)