【问题标题】:SWIG C++ to Python: terminate called after throwing an instance of ... AbortedSWIG C++ 到 Python:在抛出 ... 的实例后调用终止
【发布时间】:2017-02-21 16:10:58
【问题描述】:

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

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

【问题讨论】:

    标签: python c++ swig


    【解决方案1】:

    %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而不是值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 1970-01-01
      • 2019-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多