2024-04-26 18:05:03 发布
网友
从swig documentation
%except(python) { try { $function } catch (RangeError) { PyErr_SetString(PyExc_IndexError,"index out-of-bounds"); return NULL; } }
我将在这里添加一点,因为这里给出的示例现在说,“%except(python)”是 已弃用。。。
你现在可以(从swig 1.3.40开始,无论如何)做完全通用的,脚本语言独立的翻译。我的例子是:
%exception { try { $action } catch (myException &e) { std::string s("myModule error: "), s2(e.what()); s = s + s2; SWIG_exception(SWIG_RuntimeError, s.c_str()); } catch (myOtherException &e) { std::string s("otherModule error: "), s2(e.what()); s = s + s2; SWIG_exception(SWIG_RuntimeError, s.c_str()); } catch (...) { SWIG_exception(SWIG_RuntimeError, "unknown exception"); } }
这将在任何受支持的脚本语言中生成运行时错误异常, 包括Python,而不在其他头文件中获取Python特定的内容。
您需要将此放在需要此异常处理的调用之前。
我知道这个问题有几个星期了,但我只是在自己研究解决方案时发现的。因此,我将尝试一个答案,但我会提前警告,这可能不是一个有吸引力的解决方案,因为swig接口文件可能比手工编写包装器更复杂。而且,据我所知,swig文档从不直接处理用户定义的异常。
假设您希望抛出c++代码模块mylibrary.cpp中的以下异常,以及要在python代码中捕获的一些错误消息:
throw MyException("Highly irregular condition..."); /* C++ code */
MyException是在别处定义的用户异常。
在开始之前,请记下应该如何在python中捕获此异常。在这里,假设您有如下python代码:
import mylibrary try: s = mylibrary.do_something('foobar') except mylibrary.MyException, e: print(e)
我想这说明了你的问题。
我的解决方案包括向swig接口文件(mylibrary.i)添加以下四项:
步骤1: 在header指令(通常是未命名的{…%}块)中,为指向python感知异常的指针添加一个声明,我们将调用pMyException。下面的第2步将对此进行定义:
%{ #define SWIG_FILE_WITH_INIT /* for eg */ extern char* do_something(char*); /* or #include "mylibrary.h" etc */ static PyObject* pMyException; /* add this! */ %}
步骤2: 添加一个初始化指令(“m”特别离谱,但这正是swig v1.3.40当前在其构造的包装文件中所需要的)-在上面的步骤1中声明了pMyException:
%init %{ pMyException = PyErr_NewException("_mylibrary.MyException", NULL, NULL); Py_INCREF(pMyException); PyModule_AddObject(m, "MyException", pMyException); %}
步骤3: 如前一篇文章中所述,我们需要一个异常指令—注意,%except(python)已被弃用。这将在try-except块中包装c+++函数“do-u something”,该块捕获c++异常并将其转换为在上面的步骤2中定义的python异常:
%exception do_something { try { $action } catch (MyException &e) { PyErr_SetString(pMyException, const_cast<char*>(e.what())); SWIG_fail; } } /* The usual functions to be wrapped are listed here: */ extern char* do_something(char*);
步骤4: 由于swig在.pyd dll周围设置了一个python包装(一个“影子”模块),我们还需要确保python代码可以“看穿”到.pyd文件。下面的代码对我有用,最好直接编辑swig py包装器代码:
%pythoncode %{ MyException = _mylibrary.MyException %}
对原版海报有多大用处可能为时已晚,但也许其他人会发现上面的建议有些用处。对于小型作业,您可能更喜欢手工编码的c++扩展包装器,而不是swig接口文件的混乱。
添加:
在上面的接口文件清单中,我省略了标准的module指令,因为我只想描述使异常工作所必需的附加内容。但你的模块线应该是:
%module mylibrary
另外,setup.py(如果您使用distutils,我建议您至少开始使用distutils)应该具有类似于以下的代码,否则,当无法识别mylibrary时,步骤4将失败:
/* setup.py: */ from distutils.core import setup, Extension mylibrary_module = Extension('_mylibrary', extra_compile_args = ['/EHsc'], sources=['mylibrary_wrap.cpp', 'mylibrary.cpp'],) setup(name="mylibrary", version="1.0", description='Testing user defined exceptions...', ext_modules=[mylibrary_module], py_modules = ["mylibrary"],)
注意compile flag/EHsc,这是我在Windows上编译异常所需要的。你的平台可能不需要这个标志;谷歌有详细信息。
我已经用自己的名字测试了代码,我在这里将其转换为“mylibrary”和“MyException”,以帮助概括解决方案。希望转录错误很少或没有。要点是%init和%pythoncode指令以及
static PyObject* pMyException;
在header指令中。
希望这能澄清解决方案。
从swig documentation
我将在这里添加一点,因为这里给出的示例现在说,“%except(python)”是 已弃用。。。
你现在可以(从swig 1.3.40开始,无论如何)做完全通用的,脚本语言独立的翻译。我的例子是:
这将在任何受支持的脚本语言中生成运行时错误异常, 包括Python,而不在其他头文件中获取Python特定的内容。
您需要将此放在需要此异常处理的调用之前。
我知道这个问题有几个星期了,但我只是在自己研究解决方案时发现的。因此,我将尝试一个答案,但我会提前警告,这可能不是一个有吸引力的解决方案,因为swig接口文件可能比手工编写包装器更复杂。而且,据我所知,swig文档从不直接处理用户定义的异常。
假设您希望抛出c++代码模块mylibrary.cpp中的以下异常,以及要在python代码中捕获的一些错误消息:
MyException是在别处定义的用户异常。
在开始之前,请记下应该如何在python中捕获此异常。在这里,假设您有如下python代码:
我想这说明了你的问题。
我的解决方案包括向swig接口文件(mylibrary.i)添加以下四项:
步骤1: 在header指令(通常是未命名的{…%}块)中,为指向python感知异常的指针添加一个声明,我们将调用pMyException。下面的第2步将对此进行定义:
步骤2: 添加一个初始化指令(“m”特别离谱,但这正是swig v1.3.40当前在其构造的包装文件中所需要的)-在上面的步骤1中声明了pMyException:
步骤3: 如前一篇文章中所述,我们需要一个异常指令—注意,%except(python)已被弃用。这将在try-except块中包装c+++函数“do-u something”,该块捕获c++异常并将其转换为在上面的步骤2中定义的python异常:
步骤4: 由于swig在.pyd dll周围设置了一个python包装(一个“影子”模块),我们还需要确保python代码可以“看穿”到.pyd文件。下面的代码对我有用,最好直接编辑swig py包装器代码:
对原版海报有多大用处可能为时已晚,但也许其他人会发现上面的建议有些用处。对于小型作业,您可能更喜欢手工编码的c++扩展包装器,而不是swig接口文件的混乱。
添加:
在上面的接口文件清单中,我省略了标准的module指令,因为我只想描述使异常工作所必需的附加内容。但你的模块线应该是:
另外,setup.py(如果您使用distutils,我建议您至少开始使用distutils)应该具有类似于以下的代码,否则,当无法识别mylibrary时,步骤4将失败:
注意compile flag/EHsc,这是我在Windows上编译异常所需要的。你的平台可能不需要这个标志;谷歌有详细信息。
我已经用自己的名字测试了代码,我在这里将其转换为“mylibrary”和“MyException”,以帮助概括解决方案。希望转录错误很少或没有。要点是%init和%pythoncode指令以及
在header指令中。
希望这能澄清解决方案。
相关问题 更多 >
编程相关推荐