Skip to content

Not possible to return unique pointer to pure virtual class #641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Munken opened this issue Feb 3, 2017 · 7 comments
Closed

Not possible to return unique pointer to pure virtual class #641

Munken opened this issue Feb 3, 2017 · 7 comments

Comments

@Munken
Copy link

Munken commented Feb 3, 2017

If I try to return a unique pointer to a pure virtual class it fails due to

return_value_policy = move, but the object is neither movable nor copyable!

However it if the class is not pure virtual it works fine. Same for returning a shared pointer to it.

Below is a minimal working example based on the docs

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

class Animal {
public:
    virtual ~Animal() { }
    virtual std::string go(int n_times) = 0;
};

class Dog : public Animal {
public:
    std::string go(int n_times) override {
        std::string result;
        for (int i=0; i<n_times; ++i)
            result += "woof! ";
        return result;
    }
};

class PyAnimal : public Animal {
public:
    /* Inherit the constructors */
    using Animal::Animal;

    /* Trampoline (need one for each virtual function) */
    std::string go(int n_times) override {
        PYBIND11_OVERLOAD_PURE(
                std::string, /* Return type */
                Animal,      /* Parent class */
                go,          /* Name of function in C++ (must match Python name) */
                n_times      /* Argument(s) */
        );
    }
};

std::unique_ptr<Animal> build_dog() {
    return std::unique_ptr<Animal>(new Dog{});
}

std::shared_ptr<Animal> build_shared_dog() {
    return std::shared_ptr<Animal>(new Dog{});
}

PYBIND11_PLUGIN(PyAUSA) {


    py::module m("PyAUSA", "Python bindings for AUSAlib");

    py::class_<Animal, PyAnimal /* <--- trampoline*/> animal(m, "Animal");
    animal
            .def(py::init<>())
            .def("go", &Animal::go);

    py::class_<Dog>(m, "Dog", animal)
            .def(py::init<>());

    m.def("build_dog", &build_dog);
    m.def("build_shared_dog", &build_shared_dog);

    return m.ptr();
}

Output:

In [1]: import PyAUSA

In [2]: PyAUSA.build_shared_dog()
Out[2]: <PyAUSA.Dog at 0x7fab45d1d7e0>

In [3]: PyAUSA.build_dog()
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-3-d86cdac6dbbe> in <module>()
----> 1 PyAUSA.build_dog()

RuntimeError: return_value_policy = move, but the object is neither movable nor copyable!
@jkhoogland
Copy link

Having the same problem.

I tried to use this to solve the issue, but it doesn't.

@jagerman
Copy link
Member

jagerman commented Feb 4, 2017

Is this with current master? I can't reproduce it (but I can with the commit just before PR #607 was merged).

@jkhoogland
Copy link

I merged the PR in seperate branch as it was not yet in master, but that didn't solve it.
Still would ge the above RuntimeError.

I just tried to use my fork with the current master 20170204, but now I am getting seg fault ...

Digging further.

@jagerman
Copy link
Member

jagerman commented Feb 4, 2017

Yes, I saw that too; it happens during destruction of the instance returned via the shared_ptr. (I didn't dig into why it's happening.)

@jkhoogland
Copy link

I did a clean build of my project against my fork of the current master, and it seems to work.

I'll have a further look tommorrow.

@Munken
Copy link
Author

Munken commented Feb 4, 2017

Updating to the latest master solved the issue. Feel free to close.

@jkhoogland
Copy link

yep, i have been running various tests, it works. thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants