2017-02-21 7 views
3

SWIGモジュールを作成しようとしていますが、C++から例外をキャッチしてPythonに伝播させる方法がわかりません。ここに私のコードの簡易版です:SWIG C++からPythonへ:インスタンスをスローした後に呼び出される終了...中止

example.cpp:

#include "example.h" 

Looper::Looper() { 

    nframes = 0; 

} 

void Looper::set_nframes(int nf) { 

    if (nf < 0) { 
     throw LooperValueError(); 
    } 

    nframes = nf; 

} 

int Looper::get_nframes(void) { 

    return nframes; 

} 

example.h:

class LooperValueError {}; 

class Looper { 

    private: 
     int nframes; 

    public: 
     Looper(); 
     void set_nframes(int); 
     int get_nframes(void); 

}; 

example.i:

%module example 
%{ 
#include "example.h" 
%} 

%include "example.h" 

%exception { 
    try { 
     $function 
    } catch (LooperValueError) { 
     PyErr_SetString(PyExc_ValueError,"Looper value out of range"); 
     return NULL; 
    } 
} 

これは罰金構築します。しかし、PythonではLooper.set_nframes(-2)を呼び出すと、期待通りのValueErrorが得られません。代わりに、コードインタープリタがクラッシュする:

terminate called after throwing an instance of 'LooperValueError' 
Aborted 

例外はラッパーによって捕捉されていないようです。私は間違って何をしていますか?

答えて

2

%exceptionの効果は、それに続く宣言に対してのみローカルです。 %includeの後に%exceptionと書いたので、実際には何にも適用されません。 (これを検証するために生成されたコードを見てください - あなたのtry/catchブロックはまだ実際には出力されません)。

だからあなたのインターフェイスは、代わりに次のようになります。私は微調整

%module example 
%{ 
#include "example.h" 
%} 

%exception { 
    try { 
     $function 
    } catch (const LooperValueError&) { 
     PyErr_SetString(PyExc_ValueError,"Looper value out of range"); 
     return NULL; 
    } 
} 

%include "example.h" 

もう一つのマイナーポイント:通常、あなたは値によってcatch exceptions by const referenceの代わりに好むはずです。

関連する問題