(Swig to python) import error:dynamic module does not define init function

[亡魂溺海] 提交于 2019-12-21 17:32:06

问题


I am trying to port my c++ code to python by swig.

When I finish building the py, pyd, cxx and lib files, under Python (command line), I key in "module Dnld", it shows-> import error:dynamic module does not define init function. The following is my code,

Further: Add my build step to avoid misunderstanding, thank you Mark Tolonen

  1. File->New->Project->Windows Console Application-> Select DLL and empty project(no unicode)
  2. Add my SerialComm folder to the project(include DownloaderEngine.h Serial.h PortEnumerator.h,etc).
  3. Configuration properties->c/c++->Additional include directories->C:\Python27\include
  4. Configuration properties->Linker->General->Output File->$(OutDir)\Dnld.pyd
  5. Configuration properties->Linker->Input->Additional include directories->C:\Python27 \libs\python27.lib and .\SerialComm\setupapi.lib
  6. Add Dnld.i , do custom build
  7. Dnld.i property page->Command line->swig -c++ -python $(InputPath)
  8. Dnld.i property page->Output->$(InputName)_warp.cpp
  9. build, create Dnld_wrap.cxx, Dnld.py
  10. Add Dnld_wrap.cxx in my project, rebuild all, create Dnld.pyd, that's it

(Enviroment: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"

回答1:


Not really enough information, because the problem is likely in how you are building it. for example, with the files you've specified, building from a VS2008 command prompt should be something like:

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

Edit: Your build steps look about right, but one thing is the .pyd file is expected to be named _Dnld.pyd (note the underscore).

The generated Dnld.py calls import _Dnld (the .pyd), so you will import Dnld (the .py) in your Python script.

Example:

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

This is the error I get if I rename the .pyd without an underscore:

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

So I'm sure this will fix your issue. 我很高興幫助你!




回答2:


For the record, here another possible cause of the error message

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

Running Python2 while Swig was set up for Python3, or vice versa.




回答3:


This one took me a while to figure out. From the python.org mailing lists here, it seems the problem is that python expects module Foo to provide a function initFoo. The question then, is why doesn't Dnld provide initDnld. Since swig should handle most of that, it is probably because swig doesn't expect the finished library to be called Dnld (if it expects dnld or D_nld or anything else, it will fail, but renaming the file fixes it.) Note that this applies to any C extension for python, including those generated by pyrex/cython and boost.



来源:https://stackoverflow.com/questions/10121957/swig-to-python-import-errordynamic-module-does-not-define-init-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!