(Swig to python)导入错误:动态模块没有定义init函数

时间:2012-04-12 10:41:05

标签: c++ python swig

我试图通过swig将我的c ++代码移植到python。

当我完成构建py,pyd,cxx和lib文件时,在Python(命令行)下,我键入“module Dnld”,它显示 - > 导入错误:动态模块未定义init函数。 以下是我的代码,

进一步:添加我的构建步骤以避免误解,谢谢Mark Tolonen

  1. 文件 - >新建 - >项目 - > Windows控制台应用程序 - >选择DLL并清空项目(无unicode)
  2. 将我的SerialComm文件夹添加到项目中(包括DownloaderEngine.h Serial.h PortEnumerator.h等)。
  3. 配置属性 - > c / c ++ - >其他包含目录 - > C:\ Python27 \ include
  4. 配置属性 - >链接器 - >常规 - >输出文件 - > $(OutDir)\ Dnld.pyd
  5. 配置属性 - >链接器 - >输入 - >其他包含目录 - > C:\ Python27 \ libs \ python27.lib和。\ SerialComm \ setupapi.lib
  6. 添加Dnld.i,执行自定义构建
  7. Dnld.i属性页面 - >命令行 - > swig -c ++ -python $(InputPath)
  8. Dnld.i属性页面 - >输出 - > $(输入名称)_warp.cpp
  9. 构建,创建Dnld_wrap.cxx,Dnld.py
  10. 在我的项目中添加Dnld_wrap.cxx,重建所有,创建Dnld.pyd,就是这样
  11. (环境:带SP2008的XP SP3)

    //DownloaderEngine.h
    class __declspec(dllexport) CDownloaderEngine
    {
    public:
        CDownloaderEngine();
    
        virtual ~CDownloaderEngine();
    
        signed char OpenPort(signed char _ucPort, unsigned long _ulBaudRate, unsigned char _ucParity,
            unsigned char _ucStopBits,unsigned char _ucData);
    
        ....
    };
    
    //DownloaderEngine.cpp
    CDownloaderEngine::CDownloaderEngine()
    {
        ....
    }
    
    CDownloaderEngine::~CDownloaderEngine()
    {
        ....
    }
    
    //DownloaderEngine.i
     %module Dnld
    
     %include <windows.i>
     %include <std_vector.i>
     %include <std_map.i>
     %{
        #define SWIG_FILE_WITH_INIT
        #include ".\SerialComm\DownloaderEngine.h"
     %}
    
     /* Parse the header file to generate wrappers */
     %include ".\SerialComm\DownloaderEngine.h"
    

3 个答案:

答案 0 :(得分:6)

信息不够,因为问题可能在于您如何构建它。例如,对于您指定的文件,从VS2008命令提示符构建应该类似于:

swig -python -c++ DownloaderEngine.i
cl /LD /W4 /Fe_Dnld.pyd /Ic:\Python27\include downloaderEngine_wrap.cxx -link /LIBPATH:c:\Python27\libs DownloaderEngine.lib

编辑:您的构建步骤看起来是正确的,但有一点是.pyd文件应该命名为_Dnld.pyd(请注意下划线)。

生成的Dnld.py调用import _Dnld(.pyd),因此您将在Python脚本中import Dnld(。。)。

示例:

>>> import Dnld
>>> engine = Dnld.CDownloaderEngine()
>>> result = engine.OpenPort(...)

如果我重命名没有下划线的.pyd,这就是我得到的错误:

>>> import Dnld
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: dynamic module does not define init function (initDnld)

所以我相信这会解决你的问题。我很高兴帮助你!

答案 1 :(得分:0)

这个花了我一段时间才弄明白。从python.org邮件列表here,似乎问题是python期望模块Foo提供函数initFoo。那么问题是,为什么Dnld不提供initDnld。由于swig应该处理大部分内容,可能是因为swig不希望完成的库被称为Dnld(如果它需要dnld或D_nld或其他任何东西,它会失败,但重命名文件会修复它。)注意这个适用于python的任何C扩展,包括由pyrex / cython和boost生成的扩展。

答案 2 :(得分:0)

为了记录,这是错误消息的另一个可能原因

ImportError: dynamic module does not define init function (init<mylibrary>):

在为Python3设置Swig时运行Python2,反之亦然。