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

C++ Exceptions in SWIG typemaps

本文关键字:c++ 异常 类型 映射 SWIG      更新时间:2023-10-16

我试图用c++来包装一些简单的c++,在尝试包装最基本的东西时遇到了一个问题。

SWIG似乎没有尝试捕获可能发生在typemap内部的异常。

例如:

%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周围没有try catch

typemap只是告诉SWIG要生成什么接口代码来转换函数的调用参数和返回值。%exception在要包装的函数之前和之后立即生成代码,以将异常从c++转换为目标语言,或者将c++异常转换为等效的目标语言。如果按照SWIG文档使用%exception,您应该发现包装器函数包含为该函数指定的typemap代码,以及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
}