Use non-member method as a callback in GLUT [duplicate] - c++

This question already has answers here:
How to pass a class method as a GLUT callback?
(5 answers)
Closed 10 years ago.
I am trying to pass a function to GLUT call back glutSpecialFunc.
It's working perfectly when I try to pass a static function(specialKeyProcessor) to it.
When I moved this function to a class(KeyBoardMovement) specialized in processing keyboard-related functions it does not seem to work:
....
KeyboardMovement keyboard;
....
glutSpecialFunc(keyboard.specialKeyProcessor);
The error pops out: Reference to non-static member function must be called.
I dont understand this error because I cant see any difference between the same function placed in different places.

The glutSpecialFunc function sets a per-window callback. If you are using OpenGLUT, it also allows you to associate some data with each window using glutSetWindowData.
Therefore, you can make a global shim function like this:
void specialKeyProcessor(int key, int x, int y) {
KeyboardMovement *keyboard = static_cast<KeyboardMovement *>(glutGetWindowData());
keyboard->specialKeyProcessor(key, x, y);
}
and associate your keyboard handler using glutGetWindowData:
glutSetWindowData(static_cast<void *>(&keyboard));
If you need to store more than one piece of window data, you can store a pointer to a window-specific struct with fields for each window-specific data.
If you aren't using OpenGLUT, you can consider making a std::map mapping window IDs to your global data. Then you can take a similar approach to the above to have window-specific data.

C++ doesn't support closures, which means it can not turn a class instance, together with a method into a function pointer that when called will execute the method of the class instance.
Unfortunately GLUT doesn't support data aware callbacks, like most other C callbacks API do. So it's either write a wrapper function, that will call on a global instance of your class, or well, employ some really dirty tricks using a library called "ffcall" that can practically create new functions at runtime, which can be parametized and act as a closure you can pass to GLUT. But that's really dark stuff and the right thing would be to ditch GLUT.

Related

C++ how to write a wrapper for a C api that doesn't know about class instances?

In a project that we intended to write in C++, we use a C-library. This C library provides functions to register callbacks, that are called on each interrupt. We register our callbacks inside the constructor.
So we basically have the following (simplified) structure:
OurClass::OurClass() {
//the registerISRCallback is the C function, that accepts as first parameter the pin,
//the interrupt is expected on and as second parameter a function pointer:
//void (*callbackFunction)(int number, int time)
registerISRCallback(SCLK, handle_interrupt);
}
void OurClass::handle_interrupt(int pin, int time) {
//example: Blink a Led on the instance-LedPin
}
the problem however is twofold:
because it is a member function, the handle_interrupt method has the signature void (OurClass::*)(int, int). Therefore it is not possible to use it like this.
this class can be instantiated multiple times, so using a singleton would also not work, because our callback may differ per instance (each instance could for example have a different LedPin.
are there any more solutions to use this C API function inside our class and keep the code clean and readable?
Your class may integrate a static method that you pass as a C callback function (provided the calling conventions are made compatible; if not possible, wrap it in a pure C call).
In addition, let your class keep a static table of the created instances, in correspondence to the pins. When a callback is invoked, by knowing the pin, you will know which instance to activate.
Create a C-style API (C outside, C++ inside), which itself registers as a single callback and allows to register multiple C++ callbacks. That would require some list-handling.
When the interrupt occurs, call all of them and let them decide whether they need to react, according to the callback parameters.
Alternatively, see the more luxurious proposal (mapping pin to one of multiple callbacks) in the comment by Story Teller, which basically does the detection of which callback is needed centrally.

Casting a member function to void and later calling it with an example

Found some user attempts to invoke a member function pointer from a void pointer.
e.g.,
How to call a class member function from 2 void pointers
I would like to test it on my project, but the topics enclosed are too advanced for me and the questions usually hold partial code only.
Looking for a simple working example I could test upon.
Edit: I am trying to create a callback mechanism on my system.
so I can pass different types of callback functions without using wrapper functions or static member functions

convert double (class::*)(const gsl_vector*, void*) to double (*)(const_gsl vector*,void*) [duplicate]

So here's the situation: I'm using C++, SDL and GLConsole in conjunction. I have a class, SDLGame, which has the Init(), Loop(), Render() etc - essentially, it holds the logic for my game class.
GLConsole is a nice library so far - it lets me define CVars and such, even inside my SDL class. However, when defining commands, I have to specify a ConsoleFunc, which is typedef'd as
typedef bool (*ConsoleFunc)( std::vector<std::string> *args);
Simple enough. However, like I said, my functions are all in my class, and I know I can't pass pointer-to-class-functions as pointer-to-function arguments. I can't define static functions or make functions outside my class because some of these ConsoleFuncs must access class data members to be useful. I'd like to keep it OOP, since - well, OOP is nice.
Well, I actually have this problem "solved" - but it's extremely ugly. I just have an instance of SDLGame declared as an extern variable, and use that in my ConsoleFuncs/main class.
So, the question is: Is there a way to do this that isn't stupid and dumb like the way I am doing it? (Alternatively: is there a console library like GLConsole that supports SDL and can do what I'm describing?)
If the only interface you have is that function pointer, then you're screwed.
A member function needs a this pointer to be called, and if you have no way of passing that, you're out of luck (I guess the std::vector<std::string>* args pointer is what you get passed from the library).
In other words, even though that library uses C++ containers, it's not a good C++ library, because it relies on free functions for callbacks. A good C++ library would use boost::function or something similar, or would at the very least let you pass a void* user_data pointer that gets passed through to your callback. If you had that, you could pass the this pointer of your class, cast it back inside the callback, and call the appropriate member function.

Updating non-static members in a static function in C++

I am trying to update my camera's parameters based on my mouse movement in OpenGL. I am using GLFW. There is an predefined event handler in GLFW
glfwSetCursorPosCallback(window, mouseMoveCallback);
that i'm using to register the mouseMoveCallback() function. I have declared my Camera in a class and an instance of the Camera class is used in the program. The members in the Camera class are non-static but the mouseMoveCallback function is static. I know it is not possible for a static function to access non-static members. What is the best way I can update the members of the non-static instance of Camera's class?
I am able to gain the required functionality by using globals and using the mouseMoveCallback() function to update the globals and then reading the updated global values from the non-static member functions. But this can get ugly real quick when I want to add more parameters to read from, like keyboard inputs, etc. So I wanted to know if there is a better way of doing this
You can use glfwSet/GetWindowUserPointer to associate a user-defined pointer with a GLFWwindow object. Let's say you create a GLFWwindow pointed to by win, and a Camera object pointed to by cam - setup with:
...
glfwSetWindowUserPointer(win, cam);
glfwSetCursorPosCallback(win, mouseMoveCallback);
...
Since mouseMoveCallback is called from a C library, it has C linkage:
extern "C" void mouseMoveCallback (GLFWwindow *win, double x, double y)
{
// get the associated user-data:
Camera *cam = static_cast<Camera *>(glfwGetWindowUserPointer(win));
// manipulate the associated Camera object:
...
}
Your question requires you to decide which design to use to communicate to your object instances.
One design could be to create a global std::map of window handles as the key and object instance as the data. When the handle comes in, you search the map for the window handle and you can retrieve the object instance from there.
Another design is to see if the callback allows a "user parameter". If so, then you can attach the pointer to the instance to the user parameter. When the callback is invoked, you retrieve the instance from the "user parameter".
These are just two methods. There are others that I won't mention, but can be researched by doing a search for ways of "making an object-oriented wrapper for a 'C' interface".

How do I use tr1 function and bind for functions with changing parameters?

I'm currently going from C# to C++ and rewriting some game engine code and I think I'm at a wall with tr1; Essentially what I want to do is have an input layer take input from the touchscreen and then fire a callback to notify any elements listening to that input. Now tr1/boost seem to make this super easy via the use of function and bind, however firing callbacks that are void() is no problem, but now I'm trying to send parameters through to these callback when invoke (enums for instance).
The problem here is that when I call bind, and insert the parameter, it doesn't act as a place holder rather it acts as the permanent value to be passed. For instance my code here:
Containing class:
tr1::function<void (MenuActions action)> callback;
callback = tr1::bind(&MenuScene::handleInputCallback, this, MenuActions::neutral);
m_menuUILayer->registerCallback(callback);
Has the intent that I create a function and bind it then registerCallback passes this callback into the member class and stores the reference. This part works, but now in the member class I can invoke the callback however the default parameters are always sent...
Member class:
if (m_callback)
{
m_callback(MenuActions::backgroundTouchDown);
}
So here rather than MenuActions::backgroundTouchDown being sent to the main containing class in the callback, the default MenuActions::neutral is still being used. I'm wondering if I'm missing something, or perhaps my lack of sleep is just sending me down the wrong path? Thanks guys!
You should use placeholders
callback = tr1::bind(&MenuScene::handleInputCallback, this,
tr1::placeholders::_1);
and then call like
if (m_callback)
{
m_callback(MenuActions::backgroundTouchDown);
}
and your function handleInputCallback can have default parameter, defaulted to MenuActions::neutral