python::boost 模块优于别名:RecursionError

问题描述 投票:0回答:1

所以我正在使用 python boost。我的目标是能够从 python 模块重载 c++ 函数。我已经做到了,但在使用别名时我观察到了奇怪的行为。

我重新创建了一个基本示例来重现该错误:

#include <boost/python.hpp>
#include <iostream>
#include <string>

// CppBase class
class CppBase {
 public:
  CppBase(){};  // Default constructor

  virtual std::string myOverridableCallback() {
    return "Callback triggered from CppBase";  // Default implementation
  }

  virtual void display() {
    std::cout << "CppBase class display function" << std::endl;
    std::cout << this->myOverridableCallback() << std::endl;
  }
};

// CppBase class WRAPPER
struct CppBaseWrap : public CppBase, boost::python::wrapper<CppBase> {
 public:
  virtual std::string myOverridableCallback() override {
    // Check if override is provided in Python
    if (boost::python::override f =
            this->get_override("myOverridableCallback")) {
      return f();  // Call the Python version
    }
    return CppBase::myOverridableCallback();  // Call the Default implementation
  }
};

// CppDerived class
class CppDerived : public CppBase {
 public:
  CppDerived() {}  // Default constructor

  void show() {
    std::cout << "CppDerived class show function" << std::endl;
    std::cout << this->myOverridableCallback() << std::endl;
  }
};

using CppDerivedCopy = CppDerived;

// CppDerived class WRAPPER
struct CppDerivedWrap : public CppDerived, boost::python::wrapper<CppDerived> {
  virtual std::string myOverridableCallback() override {
    // Check if override is provided in Python
    if (boost::python::override f =
            this->get_override("myOverridableCallback")) {
      return f();  // Call the Python version
    }
    return CppBase::myOverridableCallback();  // Call the Default implementation
  }
};

BOOST_PYTHON_MODULE(InheritedFunctionTest) {
  // Expose the CppBase class
  boost::python::class_<CppBaseWrap, boost::noncopyable>("CppBase", boost::python::init<>())
      .def("myOverridableCallback", &CppBaseWrap::myOverridableCallback)
      .def("display", &CppBase::display);

  // Expose the CppDerived class
  boost::python::class_<CppDerivedWrap, boost::python::bases<CppBase>, boost::noncopyable>("CppDerived", boost::python::init<>())
      .def("myOverridableCallback", &CppDerived::myOverridableCallback)
      .def("show", &CppDerived::show);

  // Expose the CppDerivedCopy class
  boost::python::class_<CppDerivedWrap, boost::python::bases<CppBase>, boost::noncopyable>("CppDerivedCopy", boost::python::init<>())
      .def("myOverridableCallback", &CppDerivedCopy::myOverridableCallback)
      .def("show", &CppDerivedCopy::show);
}

所以如你所见,我有

using CppDerivedCopy = CppDerived;
。我的想法是能够在 python 中实现
from InheritedFunctionTest import CppDerivedCopy
并具有与
CppDerived
完全相同的行为。

我的代码可以编译,这是我的 python 基本示例:

import sys
sys.path.append('./build')
import InheritedFunctionTest


derived_obj = InheritedFunctionTest.CppDerived()
derived_obj.show()  # Calls show from Derived and myCallback from CppBase

derived_obj2 = InheritedFunctionTest.CppDerivedCopy()
derived_obj2.show()  # Calls show from Derived and myCallback from CppBase

这将触发以下错误:

Traceback (most recent call last):
  File "test_script.py", line 13, in <module>
    derived_obj.show()  # Calls show from Derived and myCallback from CppBase
RecursionError: maximum recursion depth exceeded while calling a Python object

所以这里

InheritedFunctionTest.CppDerived()
触发了这个错误。这里出现了奇怪的行为,如果在我的 cpp 代码中,我在
CppDerivedCopy
之前暴露了
CppDerived
(因此只需反转 c++ 文件中的最后 2 个代码块),我会遇到相同的错误,但在
InheritedFunctionTest.CppDerivedCopy()
对象,并且
InheritedFunctionTest.CppDerived()
对象没有引起任何问题。

因此,两个声明中的最后一个不会有问题,而第一个声明将出现此 RecursionError。

我尝试了很多不同的方法,但我没有找到问题的根源,chatGPT 也没有,谷歌也没有给我太多文档。任何帮助将不胜感激 !! 谢谢

c++ python-3.x boost-python
1个回答
0
投票

请测试下面提供的修改后的 Boost.Python 代码,看看它是否解决了递归错误。确保使用以下更改替换现有代码:

  1. call
    函数中使用
    get_override
    代替
    myOverridableCallback
virtual std::string myOverridableCallback() override {
  namespace bp = boost::python;
  bp::object pyOverride = this->get_override("myOverridableCallback");
  if (pyOverride) {
    return bp::extract<std::string>(pyOverride());
  }
  return CppBase::myOverridableCallback();
}
// Expose the CppBase class
boost::python::class_<CppBaseWrap, boost::noncopyable>("CppBase", boost::python::init<>())
    .def("display", &CppBase::display);

// Expose the CppDerived class
boost::python::class_<CppDerivedWrap, boost::python::bases<CppBase>, boost::noncopyable>("CppDerived", boost::python::init<>())
    .def("myOverridableCallback", &CppDerived::myOverridableCallback)
    .def("show", &CppDerived::show);
// Expose the CppBase class
boost::python::class_<CppBaseWrap, boost::noncopyable>("CppBase", boost::python::init<>())
    .def("display", &CppBase::display)
    .def("myOverridableCallback", &CppBase::myOverridableCallback);

// Expose the CppDerived class
boost::python::class_<CppDerivedWrap, boost::python::bases<CppBase>, boost::noncopyable>("CppDerived", boost::python::init<>())
    .def("show", &CppDerived::show);

© www.soinside.com 2019 - 2024. All rights reserved.