Search code examples
c++openglvisual-studio-2012compiler-errorstessellation

gluTessCallback error C2440


I am trying to use the function gluTessCallback but I get C2440 error. I have no idea why.

Here is the code:

#define callback void(CALLBACK*)()

template<typename T>
class Tessellation
{
private:
    GLUtesselator *pTess;

    void CALLBACK tessError(GLenum error)
    {
        sendErrorMessage((char *)gluErrorString(error), true);
    }


 public:

    void Triangulation3D(T* & point, short numOfPoints)
    {
        pTess = gluNewTess();

        gluTessCallback(pTess, GLU_TESS_ERROR,      (callback)tessError);
    }
};

The error is on gluTessCallback function:

error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'void (__stdcall *)(void)'

Why do I get this compile error?


Solution

  • The error id C2440 on Visual Studio is a type conversion error.

    The problem in your code is that you are trying to pass a class method Tessellation::tessError() as function pointer to gluTessCallback(), which expects a pointer to a global C-style function.

    A class method is very different from a free/global function and you cannot pass it as a simple function pointer because it needs an object to go along with it every time, the this pointer.

    A solution to your problem would be to declare tessError() as a static method, making it effectively the same as a free/global function scoped inside the class, like so:

    template<typename T>
    class Tessellation
    {
    private:
    
        static void CALLBACK tessError(GLenum error)
        {
            sendErrorMessage((char *)gluErrorString(error), true);
        }
        ...
    

    And pass it to gluTessCallback():

    gluTessCallback(pTess, GLU_TESS_ERROR, (callback)&Tessellation<T>::tessError);
    

    The only downside to this approach is that a static tessError() can no longer access class variables. Which doesn't seem like a problem to you, since it is not doing so right now, it appears.