Python到C ++:从Deriv到Base,再到Deriv

时间:2011-07-29 11:53:19

标签: c++ python boost

我正在使用Boost.Python将我的C ++代码暴露给Python。我遇到了一个与一个对象多次从一种语言传递到另一种语言有关的困难。这就是我想要做的事情:

C ++代码

class Base
{
  public:
    void baseTest() {
        std::cout << "Base::basetest()";
    }
};

class Deriv
    : public Base
{
  public:
    void derivTest() {
        std::cout << "Deriv::derivTest()";
    }
};

void call(Base& b, boost::python::object func)
{
    func(b);
}

BOOST_PYTHON_MODULE(event)
{
    using namespace boost;
    using namespace boost::python;

    class_<Base>("Base")
        .def("baseTest", &Base::baseTest)
    ;

    class_<Deriv, bases<Base>>("Deriv")
        .def("derivTest", &Deriv::derivTest)
    ;

    def("call", call);
}

Python代码

from event import *

def callback(deriv):
    deriv.baseTest() # works fine
    deriv.derivTest() # crash!

def run():
    d = Deriv()
    call(d, callback)

我想要发生什么

  1. C ++:调用Python中定义的run()函数。 (这里没问题)

  2. Python:run()创建一个新的Deriv对象;它通过callback函数将它和一个函数对象call传递回C ++。 (也没关系)

  3. C ++:call()Deriv对象作为Base&。它将Base-reference传递给它通过第二个参数收到的Python回调。

  4. Python:回调从C ++接收Base对象。但是,它期望它是Deriv:如果我调用derivTest()程序崩溃。但是,如果我拨打baseTest(),它就不会崩溃。

  5. 如何使回调不崩溃?

1 个答案:

答案 0 :(得分:1)

感谢您的评论,我找到了解决方案。它实际上非常简单,您只需将Base对象包装在shared_ptr中,而不是通过引用传递它,如下所示:

void call(boost::shared_ptr<Base> b, boost::python::object func)
{
    func(b);
}

但要小心一些事情。我试图使用Visual C ++ 2010 Express附带的std :: shared_ptr('内存'标题),它导致崩溃。我必须使用boost :: shared_ptr才能工作。 (我正在使用Boost版本1.46.1。)