Callbacks

machee wrote on Tuesday, May 29, 2007:

This probably isn’t directly a GLFW issue, but I figure since it’s related I’d ask for help here. I’m using Visual C++ 2005 Express.

I’m trying to use a member function of a class as a KeyCallback function. The problem I’m having is that the way I get it working, I can’t access the other members of the class within the function.

class MyClass
{
public:
static void GLFWCALL KeyCallback(int key, int action);
bool Running;
void Init();
};

void GLFWCALL MyClass::KeyCallback(int key, int action)
{
Running = false;
}

void MyClass::Init()
{
Running=true;

glfwInit\(\);
glfwOpenWindow\( 640, 480, 0,0,0,0,0,0, GLFW\_WINDOW \);
glfwSetKeyCallback \(KeyCallback\);

while \(Running\)
\{
    ...
    glfwSwapBuffers\(\);
\}

}

If I take “static” out, I can get to the other members of the class, but it won’t compile:

error C3867: ‘MyClass::KeyCallback’: function call missing argument list; use ‘&MyClass::KeyCallback’ to create a pointer to member

Changing the SetKeyCallback to &MyClass::KeyCallback also gives an error compiling:

error C2664: ‘glfwSetKeyCallback’ : cannot convert parameter 1 from ‘void (__thiscall MyClass::* )(int,int)’ to ‘GLFWkeyfun’

Changing the SetKeyCallback to just &KeyCallback gives:

error C2276: ‘&’ : illegal operation on bound member function expression

I’m not sure where to go from here…

peterpp wrote on Tuesday, May 29, 2007:

The solution I use is creating a singleton. The simplest implementation is:

class MyClass
{
public:
MyClass();
static void GLFWCALL KeyCallback(int key, int action);
bool Running;
static MyClass *Instance;
};

MyClass::MyClass()
{
Instance = this;
}

void GLFWCALL MyClass::KeyCallback(int key, int action)
{
MyClass::Instance->Running = false;
}

blundis wrote on Monday, August 25, 2008:

Hi.

I hope nobody minds me digging up this thread, but I have been trying to implement the solution shown here by Peter without much success and was hoping someone could help me.

My code looks like this:

class Input
{
public:
Input();
bool isKeyPressed(int key);
// is called by glfw, do not call
static void GLFWCALL _keyCallback(int key, int action);

static Input \*Instance;

private:
bool _keys[GLFW_KEY_LAST];
};

Input::Input()
{
Instance = this;
glfwSetKeyCallback(_keyCallback);
}

bool Input::isKeyPressed(int key)
{
return _keys[key];
}

void GLFWCALL Input::_keyCallback(int key, int action)
{
Input::Instance->_keys[key] = (action == GLFW_PRESS);
}

I just keep getting the very unhelpful error, at least to me as I’m quite new to C++:
/usr/libexec/gcc/i686-apple-darwin8/4.0.1/ld: Undefined symbols:
Input::Instance

blundis wrote on Monday, August 25, 2008:

Sorry to double post but I think my problems might be related to me completely misunderstanding how ‘static’ works. Going to look in to that by myself and see if i can come up with something.