简体   繁体   English

Object 在 Python 中通过 Pybind11 创建的 Object 未被 ZF6F87C3FDCF8B3C2FC2F07F 函数识别为派生的 class

[英]Object created in Python via Pybind11 not recognized as a derived class by C++ functions

The minimum code to reproduce the issue is as follows:重现该问题的最少代码如下:

aaa.hpp

#include <string>
#include <vector>
#include <iostream>
#include <stdexcept>
#include <cmath>
#include <cassert>
#include <utility>


template <typename D>
class BaseClass{
    /* The base class. */
protected:
    bool skip_nan = true;
};

template <typename D>
class DerivedClass : public BaseClass<D>{
public:
    explicit DerivedClass(bool skip_nan_){ this->skip_nan = skip_nan_; }
};

aaa_py.cpp

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <pybind11/stl.h>
#include "aaa.hpp"
namespace py = pybind11;


template <typename D>
void fff(BaseClass<D>& rs){

}


PYBIND11_MODULE(aaa_py, m) {
    m.def("fff_float", &fff<float>);
    py::class_<DerivedClass<float>>(m, "DerivedClass_float").def(py::init<bool>(), py::arg("skip_nan")=true);
}

test.py

import aaa_py as rsp
ds = rsp.DerivedClass_float()
rsp.fff_float(ds)

Error:错误:

Traceback (most recent call last):
  File "usage_example_python.py", line 8, in <module>
    rsp.fff_float(ds)
TypeError: fff_float(): incompatible function arguments. The following argument types are supported:
    1. (arg0: BaseClass<float>) -> None

Invoked with: <aaa_py.DerivedClass_float object at 0x000002C9EAF57308>

Basically the error is saying that function fff_float expects somebody from BaseClass<float> , but receives DerivedClass<float> .基本上错误是说 function fff_float期望有人来自BaseClass<float> ,但收到DerivedClass<float> If I change the function to accept DerivedClass<D>& , then there would be no errors.如果我将 function 更改为接受DerivedClass<D>& ,则不会出现错误。 Or, if I create an instantiation of DerivedClass<float> directly in c++ and pass it to the float_fff , there would also be no issues.或者,如果我直接在 c++ 中创建DerivedClass<float>的实例并将其传递给float_fff ,也不会有任何问题。 So it seems that the issue is that for an object created in Python, somehow the information about its base class is lost.因此,问题似乎在于,对于在 Python 中创建的 object,不知何故,有关其基础 class 的信息丢失了。 How can I deal with this?我该如何处理?

You need to declare BaseClass<float> in Python and tell pybind11 that DerivedClass_float extends it.您需要在 Python 中声明BaseClass<float>并告诉 pybind11 DerivedClass_float扩展它。

PYBIND11_MODULE(MyModule, m)
{
    m.def("fff_float", &fff<float>);

    // declare base class - this simply expose to Python, it's impossible to
    // construct a BaseClass_float in Python since no constructor is provided
    py::class_<BaseClass<float>>(m, "BaseClass_float");

    // tell pybind11 that DerivedClass<float> extends BaseClass<float>
    py::class_<DerivedClass<float>, BaseClass<float>>(m, "DerivedClass_float")
    //                              ^^^^^^^^^^^^^^^^
        .def(py::init<bool>(), py::arg("skip_nan") = true);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM