На самом деле новичок в C ++.
Я написал этот код, но говорит, что не может конвертировать из «waveOutProc» в «DWORD_PTR». Не могли бы вы сказать мне, как это исправить?
Спасибо
void CALLBACK Audio::waveOutProc(HWAVEOUT hWaveOut, unsigned int uMsg,
unsigned long dwInstance, unsigned long dwParam1,
unsigned long dwParam2)
{
/*
* pointer to free block counter
*/
int* freeBlockCounter = (int*)dwInstance;
/*
* ignore calls that occur due to openining and closing the
* device.
*/
if(uMsg != WOM_DONE) { return ; }
EnterCriticalSection(&waveCriticalSection) ;
(*freeBlockCounter)++ ;
LeaveCriticalSection(&waveCriticalSection) ;
}
////////////////////////////////////////////////// ////////////////////////////////
void Audio::playSound(const char* filename)
{
HWAVEOUT hWaveOut ;
HANDLE hFile;
WAVEFORMATEX wfx ;
char buffer[1024];
int i;
...
if(waveOutOpen(
&hWaveOut,
WAVE_MAPPER,
&wfx,
(DWORD_PTR)waveOutProc, ///////////Error Point
(DWORD_PTR)&waveFreeBlockCount,
CALLBACK_FUNCTION
) != MMSYSERR_NOERROR) {
fprintf(stderr, "unable to open wave mapper device\n");
ExitProcess(1);
}
...
}
Преобразование указателей функций в указатели данных является неопределенным поведением, поэтому вам не следует делать это в первую очередь. (Я понимаю, что функция Win API ожидает этого).
Также Вы не можете передавать функции-члены как обратные вызовы в C / C ++, если не обрабатываете неявные this
аргумент.
Ваш целевой обратный вызов имеет следующую подпись
void CALLBACK waveOutProc(
HWAVEOUT hwo,
UINT uMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
В то время как Audio :: waveOutProc, вероятно, является функцией-членом, которая подразумевает этот аргумент.
void CALLBACK waveOutProc(Audio*,
HWAVEOUT hwo,
UINT uMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
Просто определите waveOutProc
вместо статической или свободной функции.
waveOutProc — это функция, поэтому вы не можете привести ее к целочисленному типу (значению). Кроме того, я думаю, что waveOutProc также не является статическим членом вашего класса? Вы можете передавать статические функции только как функции обратного вызова.
Ошибка, которую вы опубликовали в ваших комментариях, указывает на то, что waveOutProc
является функцией-членом Audio
Класс и C ++ не позволят вам назначить функцию-член параметру или переменной, которая ожидает «нормальную» функцию. Это потому, что функции-члены имеют неявный параметр, называемый this
который является указателем на Audio
экземпляр класса.
Вместо этого считается хорошей практикой написание так называемой статической функции-члена ( static
Ключевое слово означает, что не существует неявного this
параметр), который оборачивает функцию-член, которую вы хотите вызвать. Это возможно, потому что waveOutOpen
принимает переменную пользовательских данных в качестве 5-го параметра, который затем передается статическому обратному вызову. Оболочка статической функции-члена лучше, чем просто сделать статический обратный вызов, потому что вы можете получить доступ все ваших переменных-членов классов (а не только одна переменная, например, freeBlockCounter
в твоем случае). Ваша статическая оболочка функции-члена может выглядеть так:
class Audio {
private:
int freeBlockCounter;
public:
....
static void CALLBACK waveOutProcWrapper(HWAVEOUT hWaveOut, unsigned int uMsg,
unsigned long dwInstance,
unsigned long dwParam1,
unsigned long dwParam2);
void waveOutProc(HWAVEOUT hWaveOut, unsigned int uMsg, unsigned long dwParam1,
unsigned long dwParam2);
};
и реализация wrapperProc:
void CALLBACK Audio::waveOutProcWrapper(HWAVEOUT hWaveOut, unsigned int uMsg,
unsigned long dwInstance,
unsigned long dwParam1,
unsigned long dwParam2) {
((Audio*)dwInstance)->waveOutProc(hWaveOut, uMsg, dwParam1, dwParam2);
}
Обратите внимание, как dwInstance
параметр «конвертируется» в неявный this
параметр. Теперь вы можете поставить waveOutProcWrapper
в waveOutOpen
следующим образом:
if(waveOutOpen(
&hWaveOut,
WAVE_MAPPER,
&wfx,
(DWORD_PTR)waveOutProcWrapper, ///////////Error Point
(DWORD_PTR)this,
CALLBACK_FUNCTION) != MMSYSERR_NOERROR) {
fprintf(stderr, "unable to open wave mapper device\n");
ExitProcess(1);
}