我现在正在使用Posith.python编写Python的C++扩展。此扩展中的函数可能会生成一个异常,其中包含有关错误的信息(而不仅仅是描述发生了什么的人类可读字符串)。我希望我可以将这个异常导出到Python,这样我就可以捕获它并使用额外的信息做些事情。
例如:
import my_cpp_module
try:
my_cpp_module.my_cpp_function()
except my_cpp_module.MyCPPException, e:
print e.my_extra_data
不幸的是,Posith.Python似乎将所有C++异常(即^ {CD1>}的子类)转换为^ {CD2>}。我意识到Boost.Python允许实现自定义异常转换,但是,需要使用PyErr_SetObject
,它接受一个PyObject*
(对于异常类型)和一个PyObject*
(对于异常值),这两个我都不知道如何从Boost.Python类中获取。也许有一种方法(这将是伟大的)我只是还没有找到。否则,有人知道如何导出自定义C++异常,以便我可以在Python中捕获它吗?
多亏了可变模板和广义lambda捕获,我们可以将Jack Edmond's answer折叠成更易于管理的内容,并向用户隐藏所有问题:
要将
MyCPPException
作为异常公开,只需更改py::class_
到exception_
的绑定中的py::class_
:现在我们回到Boost.Python的细节:不需要命名
class_
实例,不需要这个额外的PyObject*
,也不需要在某个地方使用额外的函数。Jack Edmonds给出的答案定义了一个不继承
Exception
(或任何其他内置Python异常类)的Python“exception”类。所以尽管它可以它不能像往常一样被抓住
Here是如何创建一个定制的Python异常类,该类将继承
Exception
。诀窍在于,所有boost::python::class_u实例都持有对对象类型的引用,可以通过它们的ptr()函数访问该类型。您可以在使用boost::python注册类时获得此信息,如下所示:
最后,当您将C++异常转换为Python异常时,您这样做如下:
下面是一个完整的工作示例:
下面是调用扩展的Python代码:
相关问题 更多 >
编程相关推荐