2013-05-20 2 views
1

Я пытаюсь создайте приложение C++, используя SDL и SDL_Mixer для аудио, и я стараюсь следовать руководству this. Однако использование Mix_HookMusicFinished() SDL_Mixer не работает, давая ошибку: аргумент типа 'void (CApp ::)()' не соответствует 'void (*)()'error: невозможно преобразовать 'void (CApp :: *)()' to 'void (*)()' для аргумента '1' to 'void Mix_HookMusicFinished (void (*)())'

Я исследовал эту ошибку , и, похоже, проблема в том, что cleanMusic является функцией-членом CApp. Однако я не могу сказать, как решить проблему, так как большинство проблем, подобных этому, сосредоточены вокруг pthread_create(). Моя функция cleanMusic() должна иметь доступ к музыке, которая является частной переменной CApp. Как я могу разрешить ошибку?

Вот код CApp.h, CApp :: handleKeyEvents() и CApp :: cleanMusic(). Дайте мне знать, если вам нужно увидеть что-то еще.

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; 
} 
+1

Apis, которые принимают 'void (*)()' callbacks suck. – Yakk

ответ

0

void cleanMusic(); является то, что известно как функция в члена. Функция-член очень отличается от нормальной функции. Причина, по которой ваш компилятор жалуется, заключается в том, что Mix_HookMusicFinished ожидает обычный указатель на функцию типа void (*)(), но вы пытаетесь передать указатель функции-члена типа void (CApp::*)(). Эти типы несовместимы.

Самым простым решением является просто сделать cleanMusic нормальной функции и Mix_Music *music; ГЛОВАЛЬНЫЙ:

Mix_Music *music; 

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

Другой способ, чтобы сделать их как static пользователей:

static void cleanMusic(); 
static Mix_Music *music_; 
+0

Являются ли глобальные переменные вполне приемлемыми для приложения, такого как игра? Я читал, что их следует избегать, но я не думаю, что могу избежать этого в этом случае, не нарушая остальную часть моего кода. Спасибо! – Qazplm123890

+0

@ Qazplm123890: Вместо глобального используйте анонимное пространство имен 'namespace {Mix_Music * music; } '. Это предотвращает проблемы с глобальными переменными, сохраняя локальное имя в исходном файле. –

1

Два изменения. Ваша функция cleanMusic должна быть статичной.

static void cleanMusic(); 

Второй регистрации крючка с:

Mix_HookMusicFinished(&CApp::cleanMusic); 

Поскольку ваш метод теперь статическим, music_ должен быть статическим, а также.

static Mix_Music *music_; 

Это означает, что для всех экземпляров CApp будет использоваться только один экземпляр этой переменной. Поскольку я не видел весь ваш код, я не могу сказать, если это проблема.

+0

Это, похоже, не сработало.Теперь я получаю сообщение об ошибке: недопустимое использование члена CApp :: music_ в статической функции-члене. – Qazplm123890

+0

Вы также обновили, где функция определена так, чтобы она была нестабильной? На самом деле это три изменения (2 связаны). –

+0

Я просто обновил объявление, потому что, если я также обновляю определение, я также получаю ошибку: не могу объявить функцию-член «static void CApp :: cleanMusic()», чтобы иметь статическую связь [-fpermissive]. – Qazplm123890

Смежные вопросы