2017-02-21 112 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代替。

相關問題