Pergunta

tentativa de definir-se uma dependência em C ++ com uma relação pai e filho. O pai contém a criança ea criança tem um ponteiro fraco para o pai.

Eu também gostaria de ser capaz de derivar do pai em Python. No entanto, quando eu faço isso, eu recebo um erro de ponteiro fraco conectando-se esse relacionamento pai-filho.

código 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;
}

ligação Python:

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

    def("create", &create);
} 

código Python:

from test_module import *

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

n = create(Test)

Erro:

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

Se eu tentar e converter o ponteiro extraído para Parent em um shared_ptr, fico com a () erro de ponteiro inválido livre em Python.

Existe uma maneira de contornar este problema ou devo desistir de usar ponteiros fracos com impulso Python?

Foi útil?

Solução

Eu joguei com o código sem o material python.

Esta reproduzido o problema:

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

O problema é nada está segurando o objeto shared_ptr. Isso corrige-o:

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

Boost.Python FAQ: "Quando um shared_ptr é convertido de Python, o shared_ptr realmente consegue uma referência para o objeto Python contendo Quando um shared_ptr está de volta convertido para Python, os controlos da biblioteca para ver se ele é um daqueles" Python gerenciadores de objetos "e se assim apenas retorna o objeto Python original"

O Pai * precisa ser armazenada em um shared_ptr de alguma forma. Eu ainda não descobri como ainda.

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

Outras dicas

A interface de class_ permite controlar como o objeto é realizada. É um parâmetro do modelo chamado HeldType. Há mais informações na documentação Boost.Python em class_, mas o seu Python ligação pode parecer mais como esta:

class_<Parent, boost::shared_ptr<Parent> >("Parent");
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top