I am trying to pass a callback function from C++ to OpenGL (C API):
gluQuadricCallback(qobj, GLU_ERROR, errorCallback);
where errorCallback is a function in a file compiled as C++ code and is declared as
void errorCallback();
The code compiles cleanly with g++ 4.4 on Linux but gives the following error with mingw32 g++ 4.4 on Windows:
..\glwidget.cpp:172: error: invalid conversion from 'void (*)()' to 'void (*)()'
..\glwidget.cpp:172: error: initializing argument 3 of 'void gluQuadricCallback(GLUquadric*, GLenum, void (*)())'
Is it some sort of C and C++ mix problem? How can I solve this?
UPDATE: void GLAPIENTRY errorCallback(); doesn’t compile either 🙁
..\glwidget.cpp:129: error: expected initializer before ‘errorCallback’
Now it’s almost sure it is a calling convention issue and has nothing to do with C linkage, see the comments below Thomas’ answer.
UPDATE 2: It seems to me I just run into a messy OpenGL issue concerning GLAPIENTRY, APIENTRY and _GLUfuncptr. Here is a VERY LONG discussion on portability issues:
http://lists.openscenegraph.org/pipermail/osg-users-openscenegraph.org/2007-October/003023.html
If that’s all you’re getting for an error, that’s a pretty shitty message. This is an issue with calling conventions.
From my
glu.h:_GLUfuncptris defined as:with
That explains the difference between Linux and mingw.
From this, you’d think you need to declare your callback as
and a
__stdcallwill be slapped onto it when appropriate.However, as Ali notes in the comments below, slapping
GLAPIENTRYonto the callback signature doesn’t always work. It seems that the GLU 1.3 spec simply specifies that avoid (*func)()is accepted. Since some implementations require a_GLUfuncptrinstead, which includes theGLAPIENTRYrequirement, but others don’t defineGLAPIENTRYat all, there is a portability problem here.A possible workaround might be:
and declare all callbacks with the
GLAPIENTRYmacro nevertheless.