2

The error is 'GLHandler::handleKeys': non-standard syntax; use '&' to create a pointer to member four times, on different functions.

I am trying to make a wrapper class for initialising glut, to make things cleaner.

The error appears on 4 lines all for the same reason, though I'm not sure why.

All of these are setting callbacks

Inside initGlut function:

glutKeyboardFunc(this->handleKeys); 
glutDisplayFunc(this->render);
glutTimerFunc(1000 / SCREEN_FPS, this->runMainLoop, 0);

Inside runMainLoop function

glutTimerFunc(1000 / this->SCREEN_FPS, this->runMainLoop, val);

The errors being thrown here do not exist when called identically from inside main which leads me to believe something is wrong with the class, but I can't see it.

Tom Martin
  • 300
  • 1
  • 2
  • 12
  • What is the exact error? Are you seeing this error when compiling or at runtime? – Retired Ninja May 06 '19 at 04:47
  • I have added it, at compile – Tom Martin May 06 '19 at 04:47
  • You need to either use a free function or a static member function as a callback. – Retired Ninja May 06 '19 at 04:48
  • I see, is there a particular reason for that limitation? – Tom Martin May 06 '19 at 04:50
  • `this->handleKeys`, `this->render` and `this->runMainLoop` are class methods rather than functions. The callback has to be a function (or a static method). – Rabbid76 May 06 '19 at 04:51
  • Sure, I understand what you said, but could you explain why that's the case, I don't see how that would be useful – Tom Martin May 06 '19 at 04:52
  • For a free or static function the signature is whatever you say it is, like `int foo(int, double);`. Id that was a member function the signature would actually be `int foo(class*, int, double);` where `class*` is your *this* pointer. The call back can't supply that this pointer so it cannot call the member function. – Retired Ninja May 06 '19 at 04:54
  • This explains it in more detail: https://stackoverflow.com/questions/6749617/how-to-use-a-c-member-function-as-the-callback-function-for-a-c-framework but I'm not sure it's really a duplicate or your problem since in that particular situation there's a parameter to the callback that could be used to store the this pointer. Glut is not quite so accommodating. :( – Retired Ninja May 06 '19 at 04:57
  • ok thanks for all of the help :) – Tom Martin May 06 '19 at 04:58
  • I will say actually, it does make sense that you cant have instances of an update, render, or keyinput function, as it is possible for only one to exist at a time. I suppose they could have used singletons instead. – Tom Martin May 06 '19 at 05:13
  • Yeah, I've used a singleton before as a dispatcher that class instances register with to get the callbacks. – Retired Ninja May 06 '19 at 13:46
  • actually, that sounds like a good idea, I'll give it a test :> – Tom Martin May 06 '19 at 20:02

1 Answers1

2

this->handleKeys, this->render and this->runMainLoop are class methods rather than functions. The callback has to be a function or a static method.

e.g. See glutDisplayFunc (and see also freeglut Application Programming Interface):

glutDisplayFunc sets the display callback for the current window.

Usage

void glutDisplayFunc(void (*func)(void));

Note, the method of a class can only be called by an object of the class. The pointer to an method is not sufficient. You can imagine the method of a class, as a function where the first parameter is the pointer to an object of the class.

If there is a class

class Foo
{
public:
    void render(void);
};

Then a pointer to the method render can be get by &Foo::render. But the type of the pointer is void(Foo::*)(void) rather than void(*)(void)

Rabbid76
  • 202,892
  • 27
  • 131
  • 174