boost python 的通用异常翻译

发布于 2024-11-27 05:43:18 字数 1634 浏览 0 评论 0原文

当前用于将特定 C++ 异常转换为 python 的 boost::python 示例如下:

void translate (const MyException& e) {
   PyErr_SetString(PyExc_RuntimeError, e.what());
}

boost::python::register_exception_translator<MyException>(translate);

不幸的是,这要求我们为每个异常编写特定的函数。我们试图通过编写一个通用异常翻译器来简化这一点:

#include <boost/python.hpp>

// Generalized exception translator for Boost Python
template <typename T> struct GeneralizedTranslator {

  public:

    void operator()(const T& cxx_except) const {
      PyErr_SetString(m_py_except, cxx_except.what());
    }

    GeneralizedTranslator(PyObject* py_except): m_py_except(py_except) {
      boost::python::register_exception_translator<T>(this);
    }

    GeneralizedTranslator(const GeneralizedTranslator& other): m_py_except(other.m_py_except) {
      //attention: do not re-register the translator!
    }

  private:

    PyObject* m_py_except;

};

//allows for a simple translation declaration, removes scope problem
template <typename T> void translate(PyObject* e) {
  ExceptionTranslator<T> my_translator(e);
}

那段代码可以工作吗, 你可以像这样包装实现“what()”的异常:

BOOST_PYTHON_MODULE(libtest)
{
  translate<std::out_of_range>(PyExc_RuntimeError);
}

不幸的是,似乎 boost::python 会将“翻译”代码作为“boost/python/detail/translate_exception.hpp”内的函数调用(第 61 行):

translate(e);

在我们的通用异常处理程序中,这将是对 GeneralizedTranslator::operator() 的调用,但这是行不通的对于 g++,给出:

error: ‘translate’ cannot be used as a function

有正确的方法来写这个吗?

The current boost::python example for translating a specific C++ exception into python goes like this:

void translate (const MyException& e) {
   PyErr_SetString(PyExc_RuntimeError, e.what());
}

boost::python::register_exception_translator<MyException>(translate);

Unfortunately, this requires that we write a specific function for each of our exceptions. We tried to simplify this, by writing a generalized exception translator:

#include <boost/python.hpp>

// Generalized exception translator for Boost Python
template <typename T> struct GeneralizedTranslator {

  public:

    void operator()(const T& cxx_except) const {
      PyErr_SetString(m_py_except, cxx_except.what());
    }

    GeneralizedTranslator(PyObject* py_except): m_py_except(py_except) {
      boost::python::register_exception_translator<T>(this);
    }

    GeneralizedTranslator(const GeneralizedTranslator& other): m_py_except(other.m_py_except) {
      //attention: do not re-register the translator!
    }

  private:

    PyObject* m_py_except;

};

//allows for a simple translation declaration, removes scope problem
template <typename T> void translate(PyObject* e) {
  ExceptionTranslator<T> my_translator(e);
}

Would that bit of code work, you could wrap exceptions that implement "what()" like this:

BOOST_PYTHON_MODULE(libtest)
{
  translate<std::out_of_range>(PyExc_RuntimeError);
}

Unfortunately, it seems boost::python will call the "translation" code as a function inside "boost/python/detail/translate_exception.hpp" (line 61):

translate(e);

In our generalized exception handler this would be a call to GeneralizedTranslator::operator() and that will not work for g++, giving:

error: ‘translate’ cannot be used as a function

Is there a correct way to write this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤千羽 2024-12-04 05:43:18

您将 this 指针作为翻译函数传递,但这会失败,因为指向对象的指针无法作为函数调用。如果您传递 *this ,这应该可以工作(请注意,这将复制构造 GeneralizedTranslator 对象)。或者您可以将注册移出构造函数,然后调用

register_exception_translator<std::out_of_range>(GeneralizedTranslator<std::out_of_range>(PyExc_RuntimeError));

You're passing the this pointer as the translate function, and this fails because a pointer to an object can't be called as a function. If you pass *this instead this should work (note that this will copy-construct the GeneralizedTranslator object). Or you can move the registration out of the constructor, and call

register_exception_translator<std::out_of_range>(GeneralizedTranslator<std::out_of_range>(PyExc_RuntimeError));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文