Overclock.net banner

1 - 7 of 7 Posts

·
Premium Member
Joined
·
5,282 Posts
Discussion Starter #1
I'm writing an opengl app (GLUT) in C++ and I'm getting an error when attempting to set the callbacks. The signature for the first is this

Code:
Code:
void glutDisplayFunc(void (*func)(void));
In one of my classes I have a function draw declared as such (irrelevant portions omitted)

Code:
Code:
#ifndef _GRAPHICS_ENGINE_H
#define _GRAPHICS_ENGINE_H

class GraphicsEngine{
public:
void draw(void);
};

#endif
In my implementation I have the following

Code:
Code:
void GraphicsEngine::draw(void){
}

void GraphicsEngine::init(int *argc, char **argv){
glutDisplayFunc(draw);
}
On compilation, I get the following error

Code:
Code:
src/GraphicsEngine.cpp:42: error: argument of type 'void (GraphicsEngine::)()' does not match 'void (*)()'
If I'm reading that error correctly its the fact that the function is a member of a class that's causing the problem. If so, how can I set a member function as the glut callback? If not, what is the problem? Thanks in advance
 

·
Registered
Joined
·
391 Posts
Quote:


Originally Posted by rabidgnome229
View Post

If I'm reading that error correctly its the fact that the function is a member of a class that's causing the problem. If so, how can I set a member function as the glut callback? If not, what is the problem? Thanks in advance

Your assumption is correct.
Every function (not static) member of a class A is really a function with an implicit first argument of type A*, and the argument is named this.
So, the signature of your draw function is really:

Code:
Code:
void GraphicsEngine::draw(GraphicsEngine *this){
}
and when you write

Code:
Code:
GraphicsEngine a;
a.draw();
you are really calling

Code:
Code:
draw(a);
and this is incompatible with the glutDisplayFunc signature.

A possible solution (but not the ONLY possible) is to use a static member function. A static function is indipendent from the class object and doesn't have the additional this argument.

Code:
Code:
class GraphicsEngine{
public:
static void draw(void);
};
 

·
Registered
Joined
·
1,984 Posts
Quote:


Originally Posted by pippolo
View Post

Your assumption is correct.
Every function (not static) member of a class A is really a function with an implicit first argument of type A*, and the argument is named this.
So, the signature of your draw function is really:

Code:
Code:
void GraphicsEngine::draw(GraphicsEngine *this){
}
and when you write

Code:
Code:
GraphicsEngine a;
a.draw();
you are really calling

Code:
Code:
draw(a);
and this is incompatible with the glutDisplayFunc signature.

A possible solution (but not the ONLY possible) is to use a static member function. A static function is indipendent from the class object and doesn't have the additional this argument.

Code:
Code:
class GraphicsEngine{
public:
static void draw(void);
};
^ This

as well you should declare as

Code:
Code:
GraphicsEngine *a;

a = new GraphicsEngine;

draw(a);
Edit: wait a sec, i may have misred ur code, you may have to use "this" in ur calls or something

i.e.

Code:
Code:
glutDisplayFunc(this::draw);

or

glutDisplayFunc(this->draw);
i think thats the syntax
 

·
Premium Member
Joined
·
5,282 Posts
Discussion Starter #4
That's abot what I figured. The class is a singleton class so I ended up putting this in my implementation file

Code:
Code:
static void draw_workaround(void){
        GraphicsEngine::instance()->draw();
}

void GraphicsEngine::glInit(int *argc, char **argv){
        glutDisplayFunc(draw_workaround);
 }
One of the first things I tried was this->draw that artard posted, but that didn't work either.
 

·
Registered
Joined
·
1,984 Posts
Quote:

Originally Posted by rabidgnome229 View Post
That's abot what I figured. The class is a singleton class so I ended up putting this in my implementation file

Code:

Code:
static void draw_workaround(void){
        GraphicsEngine::instance()->draw();
}

void GraphicsEngine::glInit(int *argc, char **argv){
        glutDisplayFunc(draw_workaround);
 }
One of the first things I tried was this->draw that artard posted, but that didn't work either.
isnt coding fun
 

·
Registered
Joined
·
391 Posts
Quote:

Originally Posted by im_not_an_artard View Post
^ This

as well you should declare as

Code:

Code:
GraphicsEngine *a;

a = new GraphicsEngine;

draw(a);
my mistake... the last row should be

Code:

Code:
draw(&a);
Quote:

Originally Posted by im_not_an_artard View Post
Edit: wait a sec, i may have misred ur code, you may have to use "this" in ur calls or something

i.e.

Code:

Code:
glutDisplayFunc(this::draw);

or

glutDisplayFunc(this->draw);
i think thats the syntax
No. The problem with a non static member function is that the invocation needs a pointer to a class object, but the invocation is made by the glut library. The glutDisplayFunc asks for a

Code:

Code:
void func(void)
function, but a non static member function is really

Code:

Code:
void func(obj*)
.

Quote:

Originally Posted by rabidgnome229 View Post
That's abot what I figured. The class is a singleton class so I ended up putting this in my implementation file

Code:

Code:
static void draw_workaround(void){
        GraphicsEngine::instance()->draw();
}

void GraphicsEngine::glInit(int *argc, char **argv){
        glutDisplayFunc(draw_workaround);
 }
One of the first things I tried was this->draw that artard posted, but that didn't work either.
the version with the draw_workaround should works (I hope !).
 

·
Registered
Joined
·
2,703 Posts
  • Rep+
Reactions: rabidgnome229
1 - 7 of 7 Posts
Top