【问题标题】:boost python: how to call a C++ virtual functionboost python:如何调用 C++ 虚函数
【发布时间】:2012-05-10 17:36:50
【问题描述】:

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

我在这里做错了什么?

【问题讨论】:

  • 你总是可以放置一个非虚拟转发函数:void Base::doFunc() { this-&gt;func(); }, .def("func", &amp;Base::doFunc);
  • 我希望避免这种开销......这不就是 boost::python 的全部意义所在吗?避免开销...?
  • @barak 你能说得更具体点吗?我以各种形式尝试过,但无法正常工作。我不想“覆盖python中的方法”我只想多态地调用一个虚拟。

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


【解决方案1】:

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

为了安全起见,它进行了复制:它确保 Python 给出的对象不会被 C++ 删除,而 Python 仍然具有对它的引用。它把它切成Base——我想——因为它对Derived一无所知。

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

  • Derived 提供一个简单的包装器。 Boost.Python 在将其转换为 Python 时仍会复制它,但它不会再将其切片为 Base

  • Base 注册一个shared_ptr 转换(通过register_ptr_to_python&lt; boost::shared_ptr&lt;Base&gt; &gt;()),在shared_ptr 中创建您的Derived 实例,并将其作为参数传递给您的Python 函数。现在 Boost.Python 知道在 Python 对象存在时不能删除 C++ 对象,因为 Python 包装器拥有一个对它的 shared_ptr 引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 2019-06-26
    • 1970-01-01
    • 2017-01-15
    • 2015-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多