0

I have a shared lib that I've created with boost python with a bunch of classes and I want to be able to inherit from these classes in python. The inheritance bit seems to work fine but I am unable to call methods in a super class.

c++ class definition:

class Game {
    vector<pair<object, Listener*> > _listeners;

public:
    Game();

    virtual void assignListener(object listener);
    vector<pair<object, Listener*> >& listeners();
};

my boost python wrapper for this class looks like this:

BOOST_PYTHON_MODULE(libgla) {
    using namespace boost::python;

    ...

    class_<Game>("Game", init<>())
            .def("assign_listener", &Game::assignListener);

    ...
};

my python test code looks like this:

from libgla import Engine, Game, Window, ErrorListener, KeyListener


class CustomGame(Game):
    def __init__(self):
        self.assign_listener(KeyListener())

engine = Engine(ErrorListener())
engine.set_game(CustomGame())
engine.set_window(Window(1280, 1024, "test"))
engine.start()

this code terminates on the assign_listener function with the following error:

Traceback (most recent call last):
  File "app.py", line 9, in <module>
    engine.set_game(CustomGame())
  File "app.py", line 6, in __init__
    self.assign_listener(KeyListener())
Boost.Python.ArgumentError: Python argument types in
    Game.assign_listener(CustomGame, KeyListener)
did not match C++ signature:
    assign_listener(Game {lvalue}, boost::python::api::object)

Am I doing something wrong or is this boost python limitation?

Note: the following python code works as it should

from libgla import Engine, Game, Window, ErrorListener, KeyListener

engine = Engine(ErrorListener())
game = Game()
game.assign_listener(KeyListener())
engine.set_game(game)
engine.set_window(Window(1280, 1024, "test"))
engine.start()

Edit 1

I think instance_holder described here is the answer however I can't figure out how to implement it and the documentation doesn't really give a clear example.

5
  • is KeyListener child of an boost::python::api::object ? Commented Dec 21, 2015 at 21:18
  • mhh no, would that cause a problem? Do you mean that I should inherit from the boost::python::api::object? Because I was under the impression that all I need to do is implement class_<KeyListener> and boost python should know about it. Commented Dec 21, 2015 at 21:20
  • i did this far away (maybe do not remember), try to do this or method "assignListener" must receive KeyListener, not object. It cannot apply your call to your method Commented Dec 21, 2015 at 21:23
  • Actually that can't be a problem because It works fine if do : game = Game() game.assign_listener(KeyListener()) Commented Dec 21, 2015 at 21:25
  • My thoughts on the problem are that c++ Boost::Python Game object doesn't recognize CustomGame as a derived class and therefore fails. It's just that the documentation is a bit sparse and I can't find a solution. Commented Dec 21, 2015 at 21:44

1 Answer 1

1

Try this:

class CustomGame(Game):
    def __init__(self):
        Game.__init__(self)
        self.assign_listener(KeyListener())

You were missing the superclass initialization. Without it, use of your base class is not really valid.

Sign up to request clarification or add additional context in comments.

2 Comments

Could you please edit in an explanation of why this code answers the question?
Thanks it worked, I can't believe I didn't even consider this. I haven't been programming in python for long, is this normal do you always have to run the super constructor even if it is just a default one?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.