Qazplm123890
Qazplm123890

Reputation: 19

error: cannot convert 'void (CApp::*)()' to 'void (*)()' for argument '1' to 'void Mix_HookMusicFinished(void (*)())'

I'm trying to create a C++ application using SDL and SDL_Mixer for audio, and am trying to follow this tutorial. However, using SDL_Mixer's Mix_HookMusicFinished() isn't working, giving the error: argument of type 'void (CApp::)()' does not match 'void (*)()'

I've researched this error, and it seems the problem is that cleanMusic is a member function of CApp. I can't tell how to solve the problem, however, since most problems similar to this one are centered around pthread_create(). My cleanMusic() function needs to be able to access music_ which is a private variable of CApp. How can I resolve the error?

Here is the code for CApp.h, CApp::handleKeyEvents(), and CApp::cleanMusic(). Let me know if you need to see something else.

CApp.h

#ifndef CAPP_H
    #define CAPP_H

#include <SDL.h>
#include <SDL_mixer.h>

#include <gl\gl.h>
#include <gl\glu.h>

class CApp {
    private:
        bool isRunning_;
    private:
        void cleanMusic();
    private:
        SDL_Surface *surfDisplay_;
        Mix_Music *music_;
        bool isRotating_;
        GLfloat rQuad_;
    public:
        CApp();
        int run();
    public:
        bool initialize();
        void handleEvents(SDL_Event *event);
        void loopData();
        void render();
        void clean();

    public:
        void handleKeyEvents(SDL_KeyboardEvent *key);
};

#endif // CAPP_H

CApp::handleKeyEvents()

#include "CApp.h"

void CApp::handleKeyEvents(SDL_KeyboardEvent *key) {
    switch(key->keysym.sym) {
        case SDLK_m:
            if (key->state == SDL_PRESSED) {
                if(music_ == NULL) {
                    music_ = Mix_LoadMUS("resources\\audio\\boop.wav");
                    Mix_PlayMusic(music_, 0);
                    Mix_HookMusicFinished(cleanMusic);

                    isRotating_ = true;
                } else {
                    Mix_HaltMusic();
                    cleanMusic();
                    isRotating_ = false;
                }
            }
            break;
        default:
            break;
    }
}

CApp::cleanMusic()

#include "CApp.h"

void CApp::cleanMusic() {
    Mix_FreeMusic(music_);
    music_ = NULL;
}

Upvotes: 1

Views: 2020

Answers (2)

Erik Nedwidek
Erik Nedwidek

Reputation: 6184

Two changes. cleanMusic needs to be static.

static void cleanMusic();

Second, you register the hook with:

Mix_HookMusicFinished(&CApp::cleanMusic);

Since your method is now static, music_ needs to be static as well.

static Mix_Music *music_;

This means that there will only be one instance of this variable shared between all instantiations of CApp. Since I haven't seen all of your code, I can't tell if this is an issue.

Upvotes: 1

Jesse Good
Jesse Good

Reputation: 52365

void cleanMusic(); is what is known as a member function. A member function is very different from a normal function. The reason your compiler complains is because Mix_HookMusicFinished expects a normal function pointer of type void (*)(), but you are trying to pass a member function pointer of type void (CApp::*)(). These types are incompatible.

The simplest solution is just to make cleanMusic a normal function and Mix_Music *music; a global:

Mix_Music *music;

void cleanMusic() {
    Mix_FreeMusic(music);
    music = NULL;
}

Another way is to make them both static members:

static void cleanMusic();
static Mix_Music *music_;

Upvotes: 0

Related Questions