2 years ago

#71873

test-img

pvallet

How to bind a C++ object to an existing python object in Pybind11?

I have made a module that uses the SDL2 library on the C++ side, and I chose to use PySDL2 to provide some existing bindings on the Python side (as manually writing all of them was out of the scope of my project).

I am currently using this workaround, which works:

class PyEventListener : public EventListener {
public:
  using EventListener::EventListener;

  bool handleEvent(SDL_Event& sdl_event) override {
    PYBIND11_OVERRIDE(bool, EventListener, handleEvent, sdl_event);
  }
};

PYBIND11_MODULE(module, m) {
  // Exposing SDL_Event as a buffer so that it can be used as a sdl2.SDL_Event in python (from pysdl2)
  
  py::class_<SDL_Event>(m, "SDL_Event", py::buffer_protocol())
    .def_buffer([](SDL_Event& event) -> py::buffer_info {
    return py::buffer_info(
      (Uint8*)&event,
      sizeof(Uint8),
      py::format_descriptor<Uint8>::format(),
      1,
      { 56 },
      { sizeof(Uint8) }
    );
  })

  py::class_<EventListener, std::shared_ptr<EventListener>, PyEventListener>(m, "EventListener")
    .def(py::init());
}

And on the Python side I have to use this:

import module

class Input(module.EventListener):
    def handleEvent(self, event):
        event = sdl2.SDL_Event.from_buffer_copy(event)

        if event.type == sdl2.SDL_MOUSEBUTTONDOWN:
            pass

My question is whether there could be a way to somehow bind the C struct SDL_Event to the existing python struct sdl2.SDL_Event so that in the above code the parameter event would be of type sdl2.SDL_Event instead of module.SDL_Event (which then requires the manual conversion).

This would be also useful the other way around as for now my only lead is to use implicit conversions between sdl2.SDL_Event and module.SDL_Event, which seems complicated not having access to sdl2.SDL_Event from my C++ module.

python

pybind11

0 Answers

Your Answer

Accepted video resources