如何在 python 中捕获异常(在 C++ 中引起)

Posted

技术标签:

【中文标题】如何在 python 中捕获异常(在 C++ 中引起)【英文标题】:How to catch exception (caused in C++) in python 【发布时间】:2015-09-04 06:35:43 【问题描述】:

我想在我的 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】:

您需要做的是在 C++ 函数中捕获异常,然后将其转换为 python 异常并将其返回给 python 代码(有关详细信息,请参阅the manual)。比如:

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(SomeException e) ,这个 SomeException 是用 C++ 还是 Python 定义的? 是C++,重点是C++和Python的异常处理不一样也不兼容。您必须将 C++ 异常转换为 python 异常,这就是示例的内容。 python 解释器将解释返回 NULL 而不是对象的 C 扩展,就像抛出异常一样(并且异常存储在由 PyErr_SetObject 设置的全局变量中)。 在我使用外部库但我无法访问 ++ 源代码但我想在 Python 中捕获 c++ 异常以使其不会崩溃 python 解释器的情况下该怎么办? @Daniel 然后我建议您编写一个非常类似于上面的包装器。除非代码已经适用于 python(在这种情况下,它应该将异常转换为开始),否则您可能需要这样做。 @Daniel 在示例中do_stuff 可能位于您没有源代码的第三方代码中。通常,如果do_stuff 不返回PyObject,您也必须将res 转换为python 对象。

以上是关于如何在 python 中捕获异常(在 C++ 中引起)的主要内容,如果未能解决你的问题,请参考以下文章

如何在非托管 C++ 中捕获托管异常(来自委托)?

SWIG:将异常从 Python 抛出到 C++

捕获多个自定义异常? - C++

如何打印 C++ 中捕获的异常的堆栈跟踪和 C++ 中的代码注入

在 C++ 中通过指针捕获异常

在一个多模块的python项目中,如何在子模块中引用项目的根目录?