如何在Python中捕获由C++引起的异常

5

我希望在我的C++应用程序中嵌入Python。我不想使用Boost库。

如果C++函数抛出异常,我想要捕获它并在我的应用程序中打印错误或获取一些详细信息,比如导致错误的Python脚本中的行号。

我该怎么做?我在Python API或C++中找不到任何获取详细异常信息的函数。

void sum(int iA, int iB)
{
    throw iA + iB;
}

from ctypes import * 

mydll = WinDLL("C:\\Users\\cppwrapper.dll")

try:
    mydll.sum(2,3)
catch:
    print "exception occured"

但是它没有起作用。请帮助我解决这个问题。提前感谢。

1个回答

7
你需要做的是在你的C++函数中捕获异常,然后将其转换为Python异常并将其返回给Python代码(有关详细信息,请参见手册)。类似于:
PyObject method(...)
{
     try {
          res = do_stuff();
          return res;
     }
     catch(SomeException e)
     {
          PyErr_SetObject(exception_type, message);
          return NULL;
     }
     catch(...)
     {
          PyErr_SetObject(PyErr_SystemError, "Unexpected exception in C++");
          return NULL;
     }
}

如果在返回到Python之前未捕获异常,则该异常可能会通过Python解释器并且可能会退出到调用Python解释器的C++函数。这可能是处理异常的不良方式,因为Python解释器将无法进行清理。省略号catch只是为了确保这种情况不会发生。

非常感谢您的回答,我有几个问题。catch(SomeException e),这个SomeException是在C++还是Python中定义的? - user5143593
这是C++的内容,关键在于C++和Python的异常处理不同也不兼容。你需要将C++的异常转换为Python的异常,这就是示例所要说明的。Python解释器会将返回NULL而不是对象的C扩展解释为抛出了异常(并且异常被存储在由PyErr_SetObject设置的全局变量中)。 - skyking
如果我正在使用外部库,但我无法访问其C++源代码,我想在Python中捕获C++异常以避免崩溃Python解释器,该怎么办? - Daniel
@Daniel 那我建议你写一个非常类似上面的包装器。除非代码已经适应于Python(在这种情况下,它应该转换异常以开始),否则你可能需要这样做。 - skyking
我无法让它工作。 我不得不更改例如PyErr_SystemError为PyExc_RuntimeError,并且消息需要用Python对象包装,例如PyUnicode_FromString(msg),才能使其编译。 但是,我仍然没有在Python中引发任何错误。 - Ben Farmer
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接