I was messing with the windows multimedia APIs and ran into this strange error running my application:
Run-Time Check Failure #0 - The value of ESP was not properly saved
I was adding a callback used by midiStreamOpen():
static void mid_callback_proc(
HMIDIOUT hmo,
UINT wMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2)
{
...
}
...
err = midiStreamOpen(
&p->stream,
&p->device,
1,
(DWORD_PTR)mid_callback_proc,
(DWORD_PTR)p,
CALLBACK_FUNCTION);
It seems I forgot the CALLBACK macro in the function definition:
static void CALLBACK mid_callback_proc(
HMIDIOUT hmo,
UINT wMsg,
DWORD_PTR dwInstance,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2)
{
...
}
The CALLBACK macro sets up the correct calling convention for the callback function. By default the calling convention is __cdecl in which the caller is required to clean up the stack. The CALLBACK macro tells the compiler to use the __stdcall calling convention for the callback function in which the called function is responsible for cleaning up the stack. If the callback uses the __cdecl calling convention, the stack is not cleaned up properly which results in the above error. Easy to miss if you’re not paying attention. ]]>