Dovydas Rupšys
Dovydas Rupšys

Reputation: 75

Create derived python class from a c++ class using Boost Python

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.

Upvotes: 0

Views: 938

Answers (1)

John Zwinck
John Zwinck

Reputation: 249592

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.

Upvotes: 1

Related Questions