Jump to content
  • Advertisement
Sign in to follow this  
Squigglyo

ESP value not saved

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!