Pybind - 使用指向派生类的共享指针调用函数

Posted

技术标签:

【中文标题】Pybind - 使用指向派生类的共享指针调用函数【英文标题】:Pybind - Invoke Function with Shared-Pointer to Derived Class 【发布时间】:2019-02-22 13:09:52 【问题描述】:

我有以下设置(1 个基类、1 个派生类、1 个容器)。容器将shared_ptr<Base> 作为输入。

#include <pybind11/pybind11.h>
namespace py = pybind11;

struct Base  ;
struct Derived : public Base  ;

struct Container  void input(const std::shared_ptr<Base>& ptr)   ;

PYBIND11_MODULE(PybindTest, m)

    py::class_<Base,    std::shared_ptr<Base>>(m, "Base").def(py::init<>());
    py::class_<Derived, std::shared_ptr<Derived>>(m, "Derived").def(py::init<>());

    py::class_<Container, std::shared_ptr<Container>>(m, "Container")
        .def(py::init<>())
        .def("input", &Container::input);

在 C++ 中,我可以将 shared_ptr&lt;Base&gt;shared_ptr&lt;Derived&gt; 传递给 input 函数。但是在 Python 中我得到一个错误:

import PybindTest as p
p.Container().input(p.Base())      # All good
p.Container().input(p.Derived())   # Throws Error

# TypeError                                 Traceback (most recent call last)
# <ipython-input-10-70fe5b9f3a41> in <module>
#       1 import PybindTest as p
#       2 p.Container().input(p.Base())
# ----> 3 p.Container().input(p.Derived())
# 
# TypeError: input(): incompatible function arguments. The following argument types are supported:
#     1. (self: PybindTest.Container, arg0: PybindTest.Base) -> None
# 
# Invoked with: <PybindTest.Container object at 0x0000022378B4FF80>, <PybindTest.Derived object at 0x0000022378B4FCE0>

我试过玩弄类似的东西

.def("input", py::overload_cast<const std::shared_ptr<Derived>&> (&Container::input))
.def("input", [](const std::shared_ptr<Derived> & ptr)  this->input(ptr); )

但是这两个都不能编译。 有什么建议吗?

我使用带有 Python 3.6 x64 的 Windows 10,并使用 VS 2019 编译所有内容。

【问题讨论】:

您可能想通过class_ 的额外参数告知 Python Base 是 Derived 的基础。 我应该在class_ 的顺序中添加那个吗? 【参考方案1】:

作为@n.m。建议:

py::class_<Derived, std::shared_ptr<Derived>, Base>(m, "Derived")
    .def(py::init<>());

来自pybind11 documentation(方法一:模板参数)

【讨论】:

以上是关于Pybind - 使用指向派生类的共享指针调用函数的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 继承中,当指向基类的指针对象指向派生类时,不调用派生类析构函数

关于C++基类、派生类的引用和指针

基类与派生类的指针和成员函数调用原理

指向抽象类的指针

使用pybind11开发python扩展库

通过指向派生类的函数调用基本虚方法