jeudi 27 août 2020

std::shared_ptr + pure virtual + overriding in python using Boost.python

I have the below use case where I want to override a pure virtual class in python and pass the shared_ptr to a C++ class. I tried the below but unable to get it work.

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/python/class.hpp>
#include <boost/python/module_init.hpp>
#include <boost/python/def.hpp>
#include <boost/python/call_method.hpp>
#include <boost/ref.hpp>
#include <memory>
#include <boost/utility.hpp>
#include <iostream>
#include <memory>
using namespace std;

class Vector : public std::enable_shared_from_this<Vector> {
    public:
        Vector() {}
        virtual void prints()
        {  std::cout << "Vector" << std::endl;    }
};

struct PyVector : Vector , boost::python::wrapper<Vector> {
    PyVector(): Vector() {}
    void prints() { this->get_override("prints")(); }
};

class Foo {
    public:
        Foo(boost::shared_ptr<Vector> vec) : _vec(vec){}
        boost::shared_ptr<Vector> _vec;
        void prints() {
            _vec -> prints();
        }
};

#include <boost/python.hpp>
using namespace boost::python;
    
BOOST_PYTHON_MODULE(Virtually) {

    class_<Vector, boost::shared_ptr<Vector>, PyVector>("vector", init<>());

    class_<Foo, boost::shared_ptr<Foo>>("foo", init<boost::shared_ptr<Vector>>())
        .def("prints", &Foo::prints);

}

For the blow python code it gives wrong values


In [3]: class MyVector(m.vector):
   ...: 
   ...:     def prints(self):
   ...:         print("MyVector")
   ...:         
   ...:     def __del__(self):
   ...:         print("I was deleted")

In [4]: x = MyVector()

In [5]: fo = m.foo(x)

In [6]: fo.prints()
Vector // It should have printed MyVector

Questions:

  1. Why am I seeing this behavior ? The method that I am overriding is not recognized ?
  2. I'd like to enhance this to work with pure virtual class (ie, Vector.prints has to be made pure virtual). How can I do that ?
  3. Instead of boost::shared_ptr, I want to use std::shared_ptr

How can I achieve them using Boost.python. If not boost python which tool and how can I implement it ?

Aucun commentaire:

Enregistrer un commentaire