7

私はswigによってc++コードをpythonに移植しようとしています。

py、pyd、cxx、libファイルの作成が終了したら、Python(コマンドライン)で「moduleDnld」と入力すると、次のように表示されます->インポートエラー:動的モジュールでinit関数が定義されていません。以下は私のコードです、

さらに:誤解を避けるためにビルドステップを追加してください、MarkTolonenに感謝します

  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を作成します。これで完了です。

(環境:VC2008を使用した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"
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は、Python スクリプトで (.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)

だから私はこれがあなたの問題を解決すると確信しています。我很高興幫助你!

于 2012-04-12T14:38:39.477 に答える
0

これは、理解するのにしばらく時間がかかりました。python.org メーリング リストhereから、python がモジュール Foo が関数 initFoo を提供することを期待していることに問題があるようです。問題は、なぜ Dnld が initDnld を提供しないのかということです。swig はそのほとんどを処理する必要があるため、おそらく swig は完成したライブラリが Dnld と呼ばれることを想定していないためです (dnld や D_nld などを想定している場合は失敗しますが、ファイルの名前を変更すると修正されます)。 pyrex/cython および boost によって生成されたものを含む、python のすべての C 拡張に適用されます。

于 2012-08-15T03:15:16.633 に答える