GLFW is a C interface, and does not support C++ objects. For the window, monitor and joystick callback functions, you can store a user pointer for each of these objects, retrieve it in the callback functions, and use that to call a member function (method) of your objects.
This is not possible with the error callback. Instead, you can use a global variable to store a pointer to a local error handler. The global error callback calls this error handler if this variable is not a nullptr
. You set this pointer before calling a GLFW function, and restore it or nullify it afterwards.
Note that this simple approach only works for single-threaded applications. If you are calling GLFW functions from multiple threads, you need to ensure the thread safety. GLFW 4 will likely improve upon this.
My C++ is very rusty, so don't expect this to work out of the box, but I believe it demonstrates what you can do:
typedef void (*glfw_error_handler_function)(void* user_data, int error_code, const char* description);
thread_local static struct glfw_error_handler_t {
void* user_data;
glfw_error_handler_function handler;
} glfw_error_handler = { NULL, NULL };
static void global_glfw_error_handler(int error_code, const char* description) {
if (glfw_error_handler.handler != NULL) {
glfw_error_handler.handler(glfw_error_handler.user_data, error_code, description);
}
}
class Window {
private:
GLFWwindow* window;
void errorCallback(int error, const char* description) {
std::cerr << "Error: " << description << std::endl;
}
public:
Window() {
window = glfwCreateWindow();
// error handling omitted for simplicity
}
void requestAttention() {
glfw_error_handler_t previousState = glfw_error_handler;
glfw_error_handler.user_data = this;
glfw_error_handler.handler = Window::errorCallback;
glfwRequestWindowAttention(window);
// Restore previous error handler state
glfw_error_handler = previousState;
}
}
static int main() {
glfwSetErrorCallback(global_glfw_error_handler);
if (!glfwInit()) {
return EXIT_FAILURE;
}
Window window();
window.requestAttention();
return 0;
}
Another possibility may be to throw a C++ error in the global error handler, and catch it at the location that calls the offending GLFW function.
C
interface glfw.org/docs/3.0/group__error.html without an additional parameter. So there is no way to pass a pointer to the class you want to handle the error.