mercredi 22 avril 2015

Implicit base conversions not occuring when passing Python objects to functions

I've hit a nasty snag in my Boost.Python adventure.

I'm trying to pass a derived class, GuiState, into a function that takes a shared_ptr to it's parent class, State.

I assumed that some sort of automatic conversion would have taken place, but I'm mistaken apparently!

This is the Boost.Python class defintion for State:

    class_<state_t, std::shared_ptr<state_t>, noncopyable>("State", init<>())
        .def("tick", &state_t::tick)
        .def("on_input_event", &state_t::on_input_event)
#if defined(MANDALA_PC)
        .def("on_window_event", &state_t::on_window_event)
#endif
        .def("on_active", &state_t::on_active)
        .def("on_passive", &state_t::on_passive)
        .def("on_enter", &state_t::on_enter)
        .def("on_exit", &state_t::on_exit)
        .def("on_stop_tick", &state_t::on_stop_tick)
        .def("on_start_tick", &state_t::on_start_tick)
        .def("on_stop_render", &state_t::on_stop_render)
        .def("on_start_render", &state_t::on_start_render)
        .def("on_stop_input", &state_t::on_stop_input)
        .def("on_start_input", &state_t::on_start_input);

And GuiState:

    class_<gui_state_t, bases<state_t>, std::shared_ptr<gui_state_t>, noncopyable>("GuiState", init<>())
        .def_readonly("layout", &gui_state_t::layout);

And StateMgr:

    class_<state_mgr_t, noncopyable>("StateMgr", no_init)
        .def("push", &state_mgr_t::push)
        .def("pop", &state_mgr_t::pop)
        .def("change_link_flags", &state_mgr_t::change_link_flags)
        .def("purge", &state_mgr_t::purge)
        .def("get_flags", &state_mgr_t::get_flags)
        .def("get_link_flags", &state_mgr_t::get_link_flags)
        .add_property("count", &state_mgr_t::count)
        .def("at", &state_mgr_t::at)
        .def("index_of", &state_mgr_t::index_of)
        .def("is_state_rendering", &state_mgr_t::is_state_rendering)
        .def("is_state_ticking", &state_mgr_t::is_state_ticking)
        .def("is_state_handling_input", &state_mgr_t::is_state_handling_input)
        .def("is_state_popping", &state_mgr_t::is_state_popping)
        .def("is_state_changing_link_flags", &state_mgr_t::is_state_changing_link_flags);

state_mgr_t::push's function signature is thus:

void push(const std::shared_ptr<state_t>& state, unsigned char link_flags);

I can then run the following script:

from mandala import *

states.push(State(), STATE_FLAG_ALL) #runs fine
states.push(GuiState(), STATE_FLAG_ALL) #error below

The last line generates the following error:

Python argument types in
    StateMgr.push(StateMgr, GuiState, int)
did not match C++ signature:
    push(struct mandala::state_mgr_t {lvalue}, class std::shared_ptr<struct mandala::state_t>, unsigned char)

I've done a bunch of searching for automatic type conversions and such but to no avail. Any help is appreciated!

Aucun commentaire:

Enregistrer un commentaire