如何通过pybind11在python中捕获C++的异常?

Posted

技术标签:

【中文标题】如何通过pybind11在python中捕获C++的异常?【英文标题】:How to catch the exception from C++ in python via pybind11? 【发布时间】:2020-06-24 01:58:44 【问题描述】:

我正在使用 pybind11 在 python 中编写代码。

比如我有test1.cpp、test_pybind.cpp和example.py

heaan_pybind.cpp

namespace py=pybind11;
PYBIND11_MODULE(test, m)

  py::class_<test1>(m, "test1")
  .def("fn", ...)

在example.py中,我想控制如下异常。

import test
while True:
  try:
    test.test1.fn(...)
  except ???:
    print("exception error.")

如何从 example.py 中的 test.cpp 捕获错误或异常?

【问题讨论】:

【参考方案1】:

简单的方法是确保您想要在 python 中捕获的所有 c++ 异常也是绑定的一部分。

所以在你的模块中,假设你有一个名为 CppExp 的 cpp 异常类型,你会做类似的事情

namespace py=pybind11;
PYBIND11_MODULE(test, m)

  py::register_exception<CppExp>(module, "PyExp");

这将创建一个名为PyExp 的新python 异常,它会导致任何抛出CppExp 的代码将其重新映射到python 异常中。

然后在你的python代码中你可以做

import test
while True:
  try:
    test.test1.fn(...)
  except test.PyExp as ex:
    print("exception error.", ex)

关于异常处理的其他 pybind11 文档在这里: https://pybind11.readthedocs.io/en/master/advanced/exceptions.html

如果您的 c++ 异常具有要转换为 python 的自定义字段或方法,则必须按照我在此处的回答实际修改 pybind11 代码: How can you bind exceptions with custom fields and constructors in pybind11 and still have them function as python exception?

【讨论】:

【参考方案2】:

如果你不知道异常的类型,你可以简单地捕获最通用的类​​型,例如Exception。见下文

import test
while True:
  try:
    test.test1.fn(...)
  except Exception:
    print("exception error.")

【讨论】:

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

使用 pybind11 通过预先存在的嵌入式 python 解释器公开 C++ 功能

基于pybind11为C++提供Python接口

Pybind11 用于 C++ 代码,内部结构通过静态工厂方法创建

如何使用 pybind11 将 python 函数转换为 std::function

Pybind11:为啥来自 Python 的异步调用不能在 C++ 中正确执行回调?

如何在pybind11中将共享指针列表传递给c++对象