我在C ++应用程序中嵌入了python。 C ++调用python并将其作为参数传递给C ++对象。该对象具有一些虚函数,并且可以是某些派生类的基类。我如何让boost :: python明白它是一个虚函数?
考虑以下因素:
在C ++中:
class Base {
public:
virtual void func();
}
class Derived {
public:
virtual void func();
}
BOOST_PYTHON_MODULE(module_api) {
class_<Base>("Base")
.def("func", &Base::func); // ?? what should I put here?
}
int main() {
//... initialization
Derived derived;
main_namespace["pyentry"](&derived);
}
在python中:
def pyentry(baseref):
baseref.func() # here I want Derived::func() to be called
我在这里做错了什么?
答案 0 :(得分:2)
这里的问题是Boost.Python深度复制派生类对象,并在将其转换为Python时将其切片到基础对象中;没有必要告诉Boost.Python关于一个虚拟的函数,除非你需要在Python中覆盖它(听起来你没有)。
它正在做那个副本是安全的:它确保Python给出的对象不会被C ++删除,而Python仍然有它的引用。它正在将其切换为Base
- 我认为 - 因为它对Derived
一无所知。
我可以想出两种方法来解决这个问题:
为Derived
提供一个简单的包装器。 Boost.Python在将其转换为Python时仍然会复制它,但是当它这样做时它不会再将它切成Base
。
为shared_ptr
注册Base
转化(通过register_ptr_to_python< boost::shared_ptr<Base> >()
),在Derived
中创建shared_ptr
个实例,并将其作为Python函数的参数。现在Boost.Python知道在Python对象存在时不能删除C ++对象,因为Python包装器持有shared_ptr
引用。