7

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

当我完成构建 py、pyd、cxx 和 lib 文件时,在 Python(命令行)下,我键入“module Dnld”,它显示-> import error:dynamic module does not define init function。以下是我的代码,

进一步:添加我的构建步骤以避免误解,谢谢 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 and .\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 with 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"
4

3 回答 3

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),因此您将import Dnld(.py)在您的 Python 脚本中。

例子:

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

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

于 2012-04-12T14:38:39.477 回答
1

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

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

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

于 2019-06-12T10:35:10.317 回答
0

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

于 2012-08-15T03:15:16.633 回答