SWIG类型映射中的C ++异常

时间:2014-06-03 10:19:54

标签: c++ swig

我尝试使用C ++来包装一些简单的C ++,并在尝试包装最基本的东西时遇到问题。

SWIG似乎没有尝试在类型映射中尝试捕获和异常。

例如,对于以下SIWG接口文件:

%module badswig

std::string func();

SWIG生成此:

SWIGINTERN PyObject *_wrap_func(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  std::string result;

  if (!PyArg_ParseTuple(args,(char *)":func")) SWIG_fail;
  result = func();
  resultobj = SWIG_NewPointerObj((new std::string(static_cast< const std::string& >(result))), SWIGTYPE_p_std__string, SWIG_POINTER_OWN |  0 );
  return resultobj;
fail:
  return NULL;
}

请注意,new std::string完全不受保护,因此如果std::bad_alloc将被抛出,它将传播到Python并崩溃。

可能还有其他案例,不仅SWIG使用new

%exception为包装函数处理此问题(如果func()抛出),但我找不到任何可以处理这种情况的字体图,特别是SWIG提供的字体。

我错过了什么吗?有没有正确处理这个?

修改
在回答答案并澄清我的问题时,%exception没有达到我的要求:

%module badswig

%exception %{
    try {
        $action
    } catch (const std::bad_alloc&) {
        PyErr_NoMemory();
        SWIG_fail;
    }
%}

std::string func();

生成这个:

SWIGINTERN PyObject *_wrap_func(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
  PyObject *resultobj = 0;
  std::string result;

  if (!PyArg_ParseTuple(args,(char *)":func")) SWIG_fail;

  try {
    result = func();
  } catch (const std::bad_alloc&) {
    PyErr_NoMemory();
    SWIG_fail;
  }

  resultobj = SWIG_NewPointerObj((new std::string(static_cast< const std::string& >(result))), SWIGTYPE_p_std__string, SWIG_POINTER_OWN |  0 );
  return resultobj;
fail:
  return NULL;
}

注意new std::string没有尝试捕捉它。

1 个答案:

答案 0 :(得分:0)

typemap只是告诉SWIG要生成什么接口代码来转换调用参数和返回函数的值。 %exception在要包装的函数之前和之后立即生成代码,将异常从C ++转换为目标语言或将C ++异常转换为目标语言等效项。如果你按照SWIG文档使用%exception,你会发现你的包装函数包含你为该函数指定的类型映射代码,以及围绕你的C ++函数的异常代码:

void swig_function(PyObj*) {
    typemap-related code to convert args from Python to C++
    exception-related code
    your-c++-func(args)
    exception-related code (catch clauses etc)
    typemap-related code to convert return value from C++ to Python
}