7

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"
4
  • 2
    +1 for "Sorry for bothering" :) Commented Apr 12, 2012 at 10:53
  • 1
    Hi,mihai, my english is not good(come from taiwan), if my grammar is not correct, i'm really sorry about it...:( Commented Apr 12, 2012 at 10:58
  • Have you looked here: swig.org/Doc1.3/Python.html? 31.2.5. Commented Apr 12, 2012 at 12:04
  • Hi,Konstantin Oznobihin, thanks for your replay:D, I've looked there, that's why I can build succeed for *.py and *.pyd file extension. I think the problem is I am not implement init function(initDnld), but I don't know how to implement for my CDownloadEngine... Commented Apr 13, 2012 at 1:24

3 Answers 3

6

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. 我很高興幫助你!

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your reply, Mark Tolonen, I've added the build step in my article, could you take a look? Thank you:)
Hello, Mark Tolonen, the result is the following(I've change to _Dnld.pyd in output) ...>>> import Dnld Traceback (most recent call last): File "<pyshell#0>", line 1, in <module> import Dnld ImportError: dynamic module does not define init function (initDnld)
Did you delete the old Dnld.pyd from the output directory? That error is from loading the non-underscore version.
Also note %module Dnld in the .i file is correct. The .pyd must be this name with the added underscore.
1

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.