область действия — обратный вызов C ++ BASS после завершения внутри класса

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

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: 🙂 вместо (*). Таким образом, проблема ясна, но, к сожалению, я недостаточно квалифицирован, чтобы ее решить. Я занимаюсь с ++ только в приватное время, и я не настолько глубоко разбираюсь в обратных вызовах, типах и областях. Не могли бы вы, люди, помочь мне найти рабочее решение без публичных методов?

Заранее спасибо!

фатальный

1

Решение

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

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

Передача функции-члена в качестве аргумента конструктору

C ++ передача функции-члена в качестве аргумента

Как я могу передать функцию-член класса в качестве обратного вызова

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

0

Другие решения

Других решений пока нет …