1

我在 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);
}

在蟒蛇中:

def pyentry(baseref):
  baseref.func()    # here I want Derived::func() to be called

我在这里做错了什么?

4

1 回答 1

2

这里的问题是 Boost.Python 在将派生类对象转换为 Python 时会深度复制您的派生类对象并将其切片为基础对象;根本不需要告诉 Boost.Python 一个函数是虚拟的,除非你需要在 Python 中重写它(听起来你不需要)。

它这样做是为了安全:它确保给定 Python 的对象不会被 C++ 删除,而 Python 仍然具有对它的引用。并且它正在将它切片Base- 我认为 - 因为它不知道任何关于Derived.

我可以想到两种方法来解决这个问题:

  • Derived. Boost.Python 在将其转换为 Python 时仍会复制它,但它不会再将其切片为 a Base

  • 为(via )注册一个shared_ptr转换,在 a 中创建您的实例,并将其作为参数传递给您的 Python 函数。现在 Boost.Python 知道当 Python 对象存在时不能删除 C++ 对象,因为 Python 包装器持有对它的引用。Baseregister_ptr_to_python< boost::shared_ptr<Base> >()Derivedshared_ptrshared_ptr

于 2012-05-12T23:23:55.767 回答