提升python:如何调用C ++虚拟函数 [英] boost python: how to call a C++ virtual function

查看:201
本文介绍了提升python:如何调用C ++虚拟函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++应用程序中嵌入了python. C ++调用python并将其作为参数传递给C ++对象.该对象具有一些虚函数,并且可以是某些派生类的基类.我如何使boost :: python理解它是一个虚函数?

I have python embedded in a C++ application. The C++ calls python and passes it as an argument a C++ object. that object has some virtual functions and can be a base class for some derived class. How do I make boost::python understand that it's a virtual function?

请考虑以下内容:
在C ++中:

consider the following:
in 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

我在做什么错了?

推荐答案

这里的问题是,Boost.Python在复制派生类对象并将其转换为Python时将其切成基础对象.除非您需要在Python中重写它(而且听起来好像不需要),否则根本不需要告诉Boost.Python函数是虚拟的.

The problem here is that Boost.Python is deep-copying your derived-class object and slicing it into a base object when it converts it to Python; there's no need to tell Boost.Python about a function being virtual at all unless you need to override it in Python (and it sounds like you don't).

这样做是为了确保安全:确定给定的对象Python不会被C ++删除,而Python仍具有对它的引用.并将它切成Base-我想-因为它对Derived一无所知.

It's doing that copy to be safe: it's making certain that the object Python is given won't be deleted by C++ while Python still has a reference to it. And it's slicing it to Base - I think - because it doesn't know anything about Derived.

我可以想到两种解决方法:

I can think of two ways to fix this:

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

  • Provide a trivial wrapper for Derived. Boost.Python will still copy it when converting it to Python, but it won't slice it into a Base anymore when it does so.

Base注册一个shared_ptr转换(通过register_ptr_to_python< boost::shared_ptr<Base> >()),在shared_ptr中创建您的Derived实例,并将其作为参数传递给您的Python函数.现在,Boost.Python知道存在Python对象时无法删除C ++对象,因为Python包装器包含对该对象的shared_ptr引用.

Register a shared_ptr conversion for Base (via register_ptr_to_python< boost::shared_ptr<Base> >()), create your Derived instance in a shared_ptr, and pass that as the argument to your Python function. Now Boost.Python knows the C++ object can't get deleted while the Python object exists, because the Python wrapper holds a shared_ptr reference to it.

这篇关于提升python:如何调用C ++虚拟函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆