2

实际上是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);
}

...
}
4

3 回答 3

5

将函数指针转换为数据指针是一种未定义的行为,因此您一开始就不应该这样做。(我了解 win api 功能正在期待这一点)。

this此外,除非您处理隐式参数,否则您不能将成员函数作为 C/C++ 中的回调传递。

您的目标回调具有以下签名

void CALLBACK waveOutProc(
  HWAVEOUT hwo,
  UINT uMsg,
  DWORD_PTR dwInstance,
  DWORD_PTR dwParam1,
  DWORD_PTR dwParam2
);

而 Audio::waveOutProc 可能是一个成员函数,它有一个隐含的 this 争论。

void CALLBACK waveOutProc(Audio*,
      HWAVEOUT hwo,
      UINT uMsg,
      DWORD_PTR dwInstance,
      DWORD_PTR dwParam1,
      DWORD_PTR dwParam2
    );

只需定义waveOutProc为静态或自由函数即可。

于 2014-02-11T13:22:41.493 回答
0

waveOutProc 是一个函数,因此您不能将其转换为整数类型(值)。此外,我想 waveOutProc 可能也不是您班级的静态成员?您只能将静态函数作为回调函数传递。

于 2014-02-11T13:21:02.077 回答
0

您在评论中发布的错误表明这waveOutProcAudio该类的成员函数,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向int 提供: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);
}  
于 2014-02-11T13:32:32.770 回答