Domanda

Prova di impostare una dipendenza in C ++ con una relazione genitore-figlio. Il genitore contiene il figlio e il figlio ha un puntatore debole sul genitore.

Vorrei anche poter derivare dal genitore in Python. Tuttavia, quando lo faccio, ricevo un errore di puntatore debole che collega questa relazione padre-figlio.

Codice C ++:

#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

using namespace boost;
using namespace boost::python;

struct Child;

struct Parent : public enable_shared_from_this<Parent>
{
    void initialize();
    shared_ptr<Child> m_child;
};

struct Child: public enable_shared_from_this<Child>
{
    void setParent(shared_ptr<Parent> ptr);
    weak_ptr<Parent> m_parent;
};

void Parent::initialize()
{
    shared_ptr<Child> ptr(new Child);
    m_child = ptr;

    m_child->setParent(shared_from_this());
}

void Child::setParent(shared_ptr<Parent> ptr)
{
    m_parent = ptr;
}

static PyObject* create(PyObject* object)
{
    PyObject* instance = PyObject_CallObject(object, NULL);

    Parent* parent = extract<Parent*>(instance);
    parent->initialize();

    return instance;
}

Associazione Python:

BOOST_PYTHON_MODULE(test_module)
{
    class_<Parent>("Parent");

    def("create", &create);
} 

Codice Python:

from test_module import *

class Test(Parent):
    def __init__(self):
        Parent.__init__(self)

n = create(Test)

Errore:

Traceback (most recent call last):
  File "main.py", line 8, in <module>
    n = create(Test)
RuntimeError: tr1::bad_weak_ptr

Se provo a convertire il puntatore estratto in Parent in un shared_ptr, visualizzo un errore di puntatore non valido () non valido in Python.

Esiste un modo per aggirare questo problema o dovrei rinunciare a usare i puntatori deboli con Boost Python?

È stato utile?

Soluzione

Ho giocato con il codice senza roba da python.

Questo ha riprodotto il problema:

Parent* p(new Parent);
p->initialize();

Il problema è che nulla sta trattenendo l'oggetto shared_ptr. Questo lo risolve:

boost::shared_ptr<Parent> p(new Parent);
p->initialize();

Domande frequenti su Boost.Python: " Quando un shared_ptr viene convertito da Python, shared_ptr gestisce effettivamente un riferimento all'oggetto Python contenente. Quando shared_ptr viene riconvertito in Python, la libreria verifica se si tratta di uno di quei "gestori oggetti Python" e in tal caso restituisce semplicemente l'oggetto Python originale "

Il genitore * deve in qualche modo essere archiviato in shared_ptr. Non ho ancora capito.

Parent* parent = boost::python::extract<Parent*>(instance);

Altri suggerimenti

L'interfaccia di class_ ti consente di controllare come viene trattenuto l'oggetto. È un parametro modello chiamato HeldType. Ci sono maggiori informazioni nella documentazione di Boost.Python su class_, ma il tuo binding Python potrebbe assomigliare di più a questo:

class_<Parent, boost::shared_ptr<Parent> >("Parent");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top