实际上是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);
}
...
}
答案 0 :(得分:5)
将函数指针转换为数据指针是一种未定义的行为,因此您不应该首先执行此操作。 (我理解win api函数正在期待这个。)
除非处理隐式this
参数,否则不能将成员函数作为C / C ++中的回调传递。
您的目标回调具有以下签名
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
定义为静态或自由函数。
答案 1 :(得分:0)
waveOutProc是一个函数,因此您无法将其强制转换为整数类型(值)。此外,waveOutProc可能也不是我认为的类的静态成员?您只能将静态函数作为回调函数传递。
答案 2 :(得分:0)
您在评论中发布的错误表明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);
}