Public Group

# ESP value not saved

This topic is 2892 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I have been racking my brain trying to figure this one out but cant do it.. can someone tell me what I am doing wrong?

The error i am getting is
 Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. 

I have googled for hours and cant find anything that points to why im having this issue.

Here is the code that is causing it.

h
 #ifndef SOUNDS_H #define SOUNDS_H #include "windows.h" #include <iostream> #include <string> #include <map> using namespace std; struct IGraphBuilder; struct IMediaControl; struct IBasicAudio; class Sounds { public: void AddSound(LPCSTR filename, std::string name); static Sounds* GetSoundEngine(); private: struct aSound { IGraphBuilder* m_graph; IMediaControl* m_playback; IBasicAudio* m_volume; bool m_ready; aSound() { m_graph = NULL; m_playback = NULL; m_volume = NULL; m_ready = false; } }; std::map<std::string, aSound*>theSounds; Sounds(); }; #endif //SOUNDS_H 

cpp
 #include <iostream> #include <string> using namespace std; #pragma comment(lib,"strmiids.lib") Sounds* Sounds::GetSoundEngine() { static Sounds* sounds = NULL; if(sounds == NULL) sounds = new Sounds(); return sounds; } Sounds::Sounds() { } void Sounds::AddSound(LPCSTR filename, std::string name) { CoInitialize(NULL); WCHAR wFile[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, filename, -1, wFile, MAX_PATH); theSounds[name] = new aSound(); if(SUCCEEDED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&theSounds[name]->m_graph))) { theSounds[name]->m_graph->QueryInterface(IID_IMediaControl, (void**)&theSounds[name]->m_playback); theSounds[name]->m_graph->QueryInterface(IID_IBasicAudio, (void**)&theSounds[name]->m_playback); if(SUCCEEDED(theSounds[name]->m_graph->RenderFile(wFile,NULL))) theSounds[name]->m_ready = true; } theSounds[name]->m_playback->Run(); } 

The error occures on the line
theSounds[name]->m_playback->Run();

##### Share on other sites
That error is often caused by stack corruption (such as a buffer overrun on a local variable).
What's going on inside that Run function?

##### Share on other sites
Run is a function of the IMediaControl variable.

Its not my function, and digging through it, i can see it comes from control.h but i cant seem to find the actual function, just a virtual empty one.
So im not sure where that bit of code looks.

##### Share on other sites
I would guess that the [font="'Courier New"]theSounds[name]->m_playback[/font] pointer isn't valid.

##### Share on other sites
Ok i feel like an idiot

 theSounds[name]->m_graph->QueryInterface(IID_IBasicAudio, (void**)&theSounds[name]->m_playback); 
needed the volume, not the playback

 theSounds[name]->m_graph->QueryInterface(IID_IBasicAudio, (void**)&theSounds[name]->m_volume); 

copying error on my part, must have misread the tut i was using.

##### Share on other sites
Is the function Run calling convention correct?
It will be wrong if the function is stdcall but the declaration is cdecl, or vice versa.

##### Share on other sites

Is the function Run calling convention correct?
It will be wrong if the function is stdcall but the declaration is cdecl, or vice versa.

Thats what i spent an hour or so looking into cause thats what that error generally means.

But the small change i made in the above post fixed it all up now and it works perfectly.
Quite angry at myself for wasting so many hours looking into the complicated error when it was just a typo...

##### Share on other sites
You shouldn't beat yourself up for just a couple of hours At the least it's one more experience under your belt.

##### Share on other sites
If you're using Visual Studio, you can go some way to mitigating 'wrong interface' errors like this by using the IID_PPV_ARGS() macro

It's used like this:
 theSounds[name]->m_graph->QueryInterface(IID_PPV_ARGS(&theSounds[name]->m_volume)); 
It combats passing the incorrect interface id by making the compiler work it out for you from the pointer type. Alternatively, the Windows SDK provides an overload for QueryInterface so you can use it like this also:
 theSounds[name]->m_graph->QueryInterface(&theSounds[name]->m_volume); 
Which works exactly the same way, but less messy.

I've no idea if these have made it to other Windows compilers/libraries apart from Microsoft's though.

##### Share on other sites

Thats what i spent an hour or so looking into cause thats what that error generally means.

But the small change i made in the above post fixed it all up now and it works perfectly.
Quite angry at myself for wasting so many hours looking into the complicated error when it was just a typo...

That's why I think C++ programmers, or all decent programmers, should know assembly language a little bit.
Sometimes for certain weird bugs, it's quite hard to debug in C++ level.
But if you track into the disassembler code, that will help much and reduce a lot of time.

I ever found a bug (99% sure) in an early version MingW gcc that failed handling stdcall properly.
My C++ code is correct, but it always crashes.
If I have no assembly knowledge, even if I wasted months, I can't find it's a bug in MingW gcc.

Just my personal experience and suggestions.

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 16
• 11
• 24
• 43
• 75