boost python:如何调用C ++虚函数

时间:2012-05-10 17:36:50

标签: c++ python boost-python virtual-functions

我在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

我在这里做错了什么?

1 个答案:

答案 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引用。