From: zikester on
I'm trying to provide a callback function to midiInOpen ( Windows MIDI
library ). The docs say the callback should be defined as:

void CALLBACK midiInProc(
HMIDIIN hMidiIn,
UINT wMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2 );

and the midiInOpen signature itself is:

MMRESULT midiInOpen(
LPHMIDIIN lphMidiIn,
UINT_PTR uDeviceID,
DWORD_PTR dwCallback,
DWORD_PTR dwCallbackInstance,
DWORD dwFlags
);

Why then does this not compile?

..
..
..
void CALLBACK midiInProc(
HMIDIIN hMidiIn,
UINT wMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2 )
{
std::cout << "Callback..." << std::endl;
}

..
..
..
if ( MMSYSERR_NOERROR != midiInOpen(
&handle,
selectedDeviceID,
&midiInProc,
NULL,
CALLBACK_FUNCTION ) )
{
std::cout << "Couldn't open midi device for input" << std::endl;
}

The error:

>c:\documents and settings\isaac\my documents\visual studio 2008\projects\midihack\midihack\midihack.cpp(47) : error C2664: 'midiInOpen' : cannot convert parameter 3 from 'void (__stdcall *)(HMIDIIN,UINT,DWORD_PTR,DWORD_PTR,DWORD_PTR)' to 'DWORD_PTR'
1> There is no context in which this conversion is possible
From: Alf P. Steinbach on
* zikester:
> I'm trying to provide a callback function to midiInOpen ( Windows MIDI
> library ). The docs say the callback should be defined as:
>
> void CALLBACK midiInProc(
> HMIDIIN hMidiIn,
> UINT wMsg,
> DWORD_PTR dwInstance,
> DWORD_PTR dwParam1,
> DWORD_PTR dwParam2 );
>
> and the midiInOpen signature itself is:
>
> MMRESULT midiInOpen(
> LPHMIDIIN lphMidiIn,
> UINT_PTR uDeviceID,
> DWORD_PTR dwCallback,
> DWORD_PTR dwCallbackInstance,
> DWORD dwFlags
> );
>
> Why then does this not compile?
>
> .
> .
> .
> void CALLBACK midiInProc(
> HMIDIIN hMidiIn,
> UINT wMsg,
> DWORD_PTR dwInstance,
> DWORD_PTR dwParam1,
> DWORD_PTR dwParam2 )
> {
> std::cout << "Callback..." << std::endl;
> }
>
> .
> .
> .
> if ( MMSYSERR_NOERROR != midiInOpen(
> &handle,
> selectedDeviceID,
> &midiInProc,
> NULL,
> CALLBACK_FUNCTION ) )
> {
> std::cout << "Couldn't open midi device for input" << std::endl;
> }
>
> The error:
>
>> c:\documents and settings\isaac\my documents\visual studio 2008\projects\midihack\midihack\midihack.cpp(47) : error C2664: 'midiInOpen' : cannot convert parameter 3 from 'void (__stdcall *)(HMIDIIN,UINT,DWORD_PTR,DWORD_PTR,DWORD_PTR)' to 'DWORD_PTR'
> 1> There is no context in which this conversion is possible

Try

if ( MMSYSERR_NOERROR != midiInOpen(
&handle,
selectedDeviceID,
reinterpret_cast<DWORD_PTR>( &midiInProc ),
0,
CALLBACK_FUNCTION ) )
{
std::cout << "Couldn't open midi device for input" << std::endl;
}

The reason for the ungood formal argument type is that the function can accept
different things there: a callback function, a thread handle or a window handle.

It's just bad design, it should have been split as three different functions.


Cheers & hth.,

- Alf