SWIG C ++到Python:抛出一个实例后终止调用...已中止

时间:2017-02-21 16:10:58

标签: python c++ swig

我正在尝试编写一个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

似乎异常没有被包装器捕获。我做错了什么?

1 个答案:

答案 0 :(得分:2)

%exception的效果仅限于其后的声明。您在%exception之后编写了%include,因此它实际上并未应用于任何内容。 (看看生成的代码来验证这一点 - 你的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而不是价值。