简体   繁体   中英

Error by wrapping C++ abstract class with pybind11

I'm trying to make a simple example to wrap an abstract C++ class with pybind. The code is:

#include <pybind11/pybind11.h>
#include <ostream>
#include <iostream>
namespace py = pybind11;
using namespace std;

class Base
{
public:
    virtual void test() = 0;

};
class Derived: public Base
{
public:
    void test() {cout << "Test";}
};


PYBIND11_MODULE(example,m) {
    py::class_<Base, Derived>(m, "Base")
        .def(py::init<>())
        .def("test", &Derived::test);
}

And while I run the following command

c++ -O3 -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` abstract_test.cpp -o example`python3-config --extension-suffix`\n

I get the error:

In file included from abstrakt_test.cpp:1:
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h: In instantiation of ‘Return (Derived::* pybind11::method_adaptor(Return (Class::*)(Args ...)))(Args ...) [with Derived = Base; Return = void; Class = Derived; Args = {}]’:
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h:1118:45:   required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def(const char*, Func&&, const Extra& ...) [with Func = void (Derived::*)(); Extra = {}; type_ = Base; options = {Derived}]’
abstrakt_test.cpp:23:36:   required from here
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h:1032:19: error: static assertion failed: Cannot bind an inaccessible base class method; use a lambda definition instead
     static_assert(detail::is_accessible_base_of<Class, Derived>::value,
                   ^~~~~~
/home/anaconda3/envs/pybind/lib/python3.8/site-packages/pybind11/include/pybind11/pybind11.h:1034:12: error: cannot convert ‘void (Derived::*)()’ to ‘void (Base::*)()’ in return
     return pmf;
            ^~~

You need to "wrap" Base as well. Otherwise you are going to get following exception at import time:

ImportError: generic_type: type "Derived" referenced unknown base type "Base"

Also, wrapping order of Derived is wrong:

py::class_<Derived, Base>(m, "Derived")

Full example:

PYBIND11_MODULE(example,m) {
    py::class_<Base>(m, "Base");

    py::class_<Derived, Base>(m, "Derived")
            .def(py::init<>())
            .def("test", &Derived::test);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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