2016-01-09 4 views
1

У меня есть небольшая проблема с использованием библиотеки BASS в C++. Игра работает нормально, но я хочу перейти к следующему файлу, после того, как текущий проигрывается до конца. Для такого рода потребности БАС предоставляет обратные вызовы, и я использую его следующим образом (INIT уже сделано) ...C++ BASS callback после завершения внутри класса

foo.h:

class Foo 
{ 
    public: 
     Foo(void); 
     ~Foo(void); 
     void endOfFile(void); 
    private: 
     HSTREAM _streamHandle; 
     void playFile(string); 
}; 

foo.cpp:

void Foo::playFile(string fileName) 
{ 
    _streamHandle = BASS_StreamCreateFile(false, fileName.c_str(), 0, 0, BASS_STREAM_AUTOFREE); 
    BASS_ChannelSetSync(_streamHandle, BASS_SYNC_END, 0, endOfFileCallback, this); 
    BASS_ChannelPlay(_streamHandle, true); 

void Foo::endOfFile() 
{ 
    playFile(getNextFileFromSomewhere()); // obviously this is done different in production code 
} 

void CALLBACK endOfFileCallback(HSYNC handle, DWORD channel, DWORD data, void* pTarget) 
{ 
    Foo* pFoo = static_cast<Foo*>(pTarget); 
    pFoo->endOfFile(); 
} 

Итак, это работает, но оно кажется уродливым, но имеет функцию, а не метод, называемый обратным вызовом, и противопоставляет endOfFile в качестве общедоступного метода. Он должен быть закрытым. Так что я пытался использовать метод в качестве обратного вызова ...

bar.h:

class Bar 
{ 
    public: 
     Bar(void); 
     ~Bar(void); 
    private: 
     HSTREAM _streamHandle; 
     void playFile(string); 
     void endOfFile(void); 
     void CALLBACK endOfFileCallback(HSYNC, DWORD, DWORD, void*); // now declaration in class 
}; 

Bar.cpp:

void Bar::playFile(string fileName) 
{ 
    _streamHandle = BASS_StreamCreateFile(false, fileName.c_str(), 0, 0, BASS_STREAM_AUTOFREE); 
    BASS_ChannelSetSync(_streamHandle, BASS_SYNC_END, 0, endOfFileCallback, 0); // no reference to 'this' needed 
    BASS_ChannelPlay(_streamHandle, true); 

void Bar::endOfFile() 
{ 
    playFile(getNextFileFromSomewhere()); // obviously this is done different in production code 
} 

void CALLBACK Bar::endOfFileCallback(HSYNC handle, DWORD channel, DWORD data, void* pTarget) 
{ 
    endOfFile(); 
} 

Но это не компилируется: - (

error: cannot convert 
    ‘Bar::endOfFileCallback’ 
from type 
    ‘void (Bar::)(HSYNC, DWORD, DWORD, void*) {aka void (**Player**::)(unsigned int, unsigned int, unsigned int, void*)}’ 
to type 
    ‘void (*)(HSYNC, DWORD, DWORD, void*) {aka void (*)(unsigned int, unsigned int, unsigned int, void*)}’ 

Я думаю, вы видите разницу (Bar: :) вместо (*). Итак, проблема ясна, но, к сожалению, я недостаточно квалифицирован, чтобы ее решить. Я делаю C++ только в приватное время, и я не настолько глубоко в обратных вызовах, типах и областях. Можете ли вы помочь мне найти рабочее решение без публичных методов?

Заранее благодарен!

Fatal

ответ

0

У меня была такая же ошибка. Я также новичок в C++.

В C++ существует большая разница между указателями на функции и указателями на функции-члены. Эти ответы помогли мне:

Passing a member function as an argument to a constructor

C++ passing member function as argument

How can I pass a class member function as a callback

Поэтому либо использовать функцию члена с помощью перечисленных ответов, использовать статические функции или просто использовать простые старые функции которые не относятся к классу.