【发布时间】:2011-07-29 11:53:18
【问题描述】:
我正在使用 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)
我想要发生的事情
C++:调用 Python 中定义的
run()函数。 (这里没问题)Python:
run()创建一个新的Deriv对象;它通过call函数将它和一个函数对象callback传递回C++。 (也可以)C++:
call()将Deriv对象作为Base&。它将 Base-reference 传递给它通过第二个参数接收到的 Python 回调。Python:回调从 C++ 接收
Base对象。但是,它希望它是Deriv:如果我调用derivTest(),程序就会崩溃。但是,如果我调用baseTest(),它不会崩溃。
如何让回调不崩溃?
【问题讨论】:
-
也许(我不太确定),你应该将
baseTest设为虚拟(并添加一个虚拟析构函数)。 -
baseTest不需要是虚拟的,因为它没有被覆盖。 -
@Alexandre, Mike:将
baseTest虚拟化确实没有意义。添加 anything 虚拟(可能应该是析构函数)可能会有所帮助,因为拥有虚拟方法允许 C++ 运行时检查运行时类型。 -
@Jan:哦,我读得太快了……但是,我最初的想法是 RTTI 是不可能的,因为你的类不是多态的(因此崩溃)。但是您会收到一条编译器消息。