开发者

Python to C++: From Deriv, to Base, to Deriv again

I'm using Boost.Python to expose my C++ code to Python. I've encountered a difficulty related to having an object passed from one language to the other multiple times. Here's what I want to do:

The C++ code

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("de开发者_如何学运维rivTest", &Deriv::derivTest)
    ;

    def("call", call);
}

Python code

from event import *

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

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

What I want to happen

  1. C++: Calls the run() function defined in Python. (No problem here)

  2. Python: run() creates a new Deriv object; it passes it and a function object, callback, back to C++, through the call function. (Also okay)

  3. C++: call() takes the Deriv object as a Base&. It passes the Base-reference to the Python callback it received through the second parameter.

  4. Python: The callback receives the Base object from C++. However, it expects it to be a Deriv: if I call derivTest() the program crashes. However, if I call baseTest(), it doesn't crash.

How can I make the callback not crash?


Thanks for the comments, I found the solution to this. It's actually quite simple, you just have to wrap the Base object in a shared_ptr instead of passing it by reference, like this:

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

But be careful about something. I tried to used std::shared_ptr that comes with Visual C++ 2010 Express (the 'memory' header) and it caused a crash. I had to use the boost::shared_ptr for it to work. (I'm using version 1.46.1 of Boost.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜