Frage

Actually newbie in c++. I wrote this code but says cannot convert from "waveOutProc" to "DWORD_PTR".Would you tell me how to fix it?

thanks

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);
}

...
}
War es hilfreich?

Lösung

Converting function pointers to data pointers is an undefined behaviour so you shouldn't do this in the first place. (I understand the win api function is expecting this).

Also You cannot pass member functions as callbacks in C/C++ unless you handle the implicit this argument.

Your target callback has the following signature

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

While Audio::waveOutProc is probably a member function which has an implicit this arguement.

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

Just define waveOutProc as static or free function instead.

Andere Tipps

waveOutProc is a function, so you cannot cast it to an integral type (value). Furthermore, waveOutProc is probably also not a static member of your class I suppose? You can only pass static functions as callback functions.

The error you posted in your comments indicates that waveOutProc is a member function of the Audio class and C++ will not allow you to assign a member function to a parameter or variable that expects a "normal" function. This is because member functions have an implicit parameter called this which is a pointer to an Audio class instance.

Instead it is considered good practice to write a so-called static member function (the static keyword means that there is no implicit this parameter) which wraps the member function you want to call. This is possible because waveOutOpen takes a user-data variable as it's 5th parameter which is then passed to the static callback. A static member function wrapper is better than just making your callback static because you can then access all of your classes member variables (and not only one variable, for example freeBlockCounter in your case). Your static member function wrapper could look like this:

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);
};

and implementation of the 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);
}

Notice how the dwInstance parameter is "converted" to the implicit this parameter. You can now supply waveOutProcWrapper to waveOutOpen int the following way:

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);
}  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top