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

2024-05-15 21:32:24 发布

您现在位置:Python中文网/ 问答频道 /正文

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

当我构建完py、pyd、cxx和lib文件后,在Python(命令行)下输入“module Dnld”,它显示->;导入错误:动态模块没有定义in it函数。 以下是我的代码

进一步:添加我的构建步骤以避免误解,谢谢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属性页->;输出->;$(InputName)_warp.cpp
  9. 生成,创建Dnld_wrap.cxx,Dnld.py
  10. 在我的项目中添加Dnld_wrap.cxx,全部重建,创建Dnld.pyd,就这样

(环境:XP SP3和VC2008)

//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"

Tags: 文件项目gt属性includelibcxxpyd
3条回答

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

没有足够的信息,因为问题可能出在你如何构建它。例如,对于您指定的文件,从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(The.pyd),因此您将在Python脚本中import Dnld(The.py)。

示例:

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

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

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

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

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

相关问题 更多 >