Thread: [C++] "the value of ESP was not properly saved across a function call."

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    49

    [C++] "the value of ESP was not properly saved across a function call."

    salutations,

    compiler: VC++ 6.0.
    we are relatively new to C++ programming. we are trying to access a DLL, created in VB6, from C++.
    to use the DLL, we used the #import command, and some other functions that were shown in a tutorial that we don't remember where we found.
    initializing the DLL (COM) works; the problem arises when we try to call a function of it. the program's code is below. the VB DLL's project is named mbr and it contains a class named mbrl. when the function t->speak(...) is called, the following error happens:

    "File: i386/chkesp.c
    Line: 42

    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."

    here is the code (a small program):
    Code:
    #import "C:\WINDOWS\system32\mbr.dll"
    #include "iostream"
    #include <windows.h>
    using namespace std;
    using namespace mbr;
    
    int main(int argc, char* argv[])
    {
     
         HRESULT hresult;
         CLSID clsid;
         _mbrl *t;
    			_bstr_t		bstrValue("k 100 100\n");
    			_bstr_t		dbe("ar1");
    			_bstr_t		oute("OUT.WAV");
    			_bstr_t		bstrR("");
    			long		freqe;
    			long		dure;
    			long		vole;
    			long		pite;
    			long		returne;
    			freqe = 1;
    			dure = 1;
    			vole = 1;
    			pite = 1;
         ::CoInitialize(NULL);
          hresult=CLSIDFromProgID(OLESTR("mbr.mbrl"), &clsid);
          hresult= CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
                                       __uuidof(_mbrl),(LPVOID*) &t);
          if(hresult == S_OK)
          {
             
    		 returne = t->speak(bstrValue, freqe, dure, vole, pite, dbe, oute); // <- ERROR HAPPENS HERE
             t->Release();
    		 ::CoUninitialize;
           }
         return 0;
    }
    thank you in advance.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You have a mismatched DLL. In other words the version of the header you are using does not match the version of the DLL. You may be calling function foo() but inside the DLL bar() is actually getting called or it could be calling into the middle of foo().

    The debugger will most likely not point to any line that makes sense. I've actually had code that ran but called the wrong function in the DLL. It's a simple matter of the offsets being incorrect. It's possible that the code is jumping into the middle of a function, end of a function, etc.

  3. #3
    Registered User
    Join Date
    Apr 2008
    Posts
    49
    Quote Originally Posted by Bubba View Post
    You have a mismatched DLL. In other words the version of the header you are using does not match the version of the DLL. You may be calling function foo() but inside the DLL bar() is actually getting called or it could be calling into the middle of foo().

    The debugger will most likely not point to any line that makes sense. I've actually had code that ran but called the wrong function in the DLL. It's a simple matter of the offsets being incorrect. It's possible that the code is jumping into the middle of a function, end of a function, etc.
    thank you for the response, but we don't actually understand what you mean. what do you mean by the "header we are using"? how could we solve this? how can we fix these offsets?
    we know that, even with the function not working, the DLL actually loads (we know this because, when it loads, the first thing the DLL does is to show its license agreement dialog box).

    thank you for your patience.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I have no experience trying to call a VB6 DLL from C++. I do have experience calling a C# DLL from C++ so I'm fairly sure they are a bit similar. I'm assuming you have some type of header that acts as an interface to the DLL?

    Often what happens is you are using a version 1.0 header with a version 2.0 library. What happens is that a function call in 1.0 may not map to the code in the 2.0 DLL. So you have a DLL mismatch. The code is calling a DLL function that either does not exist or is at the incorrect address in the DLL. Sometimes Visual Studio figures it out but sometimes it will call the wrong function (if the old address just so happens to be the same address as a new/existing function) and sometimes it throws the ESP exception.

    I ran into this at work when my DLLs were not the correct version. It's a well known error at my workplace and when we get it we know exactly what went wrong. We just need to update and/or rebuild our DLLs and then re-compile the solution. Anytime you get this ESP error when working with DLLs you usually have a DLL version mismatch.

    If you are using different calling conventions this error can also pop up as MSDN states. You need to check the VB6calling convention and make sure it matches your current calling convention in C++.
    Last edited by VirtualAce; 06-08-2008 at 02:05 PM.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If I'm not mistaken, VB works with __stdcall. At least that's what you need to use when calling a C++ dll from VB. But that's about all I know. I have never done the reverse.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Apr 2008
    Posts
    49
    thank you for the responses.
    actually - remarking that we are beginners - we don't know what you mean by using a header for the DLL. what we did was just using the #import function, and then CoInitialize, CoCreateInstance and calling the function.
    we tried to recompile the DLL in VB as you said, but it didn't work.
    any ideas?
    thank you for your patience.

  7. #7
    Registered User
    Join Date
    Apr 2008
    Posts
    49
    we discovered something new about this error:
    actually, the problem is not with the speak() function. the problem is that our DLL, mbr.DLL, itself communicates with another DLL, which was not created by us.
    the VB project of mbr.DLL has a module which declares external function calls to this other DLL. when we erase the function calls to this other DLL from speak(), that error doesn't happen anymore (of course, those function calls are important, so we can't keep speak() without them).
    so, the problem is not with speak() itself, but with the interior of it. but we don't have any idea on how we could solve this.
    any ideas? is there any more information we can give to help discovering how to solve it?
    thank you in advance.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. Brand new to C need favor
    By dontknowc in forum C Programming
    Replies: 5
    Last Post: 09-21-2007, 10:08 AM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Unknown C ESP function call error message
    By wbeasl in forum C Programming
    Replies: 1
    Last Post: 10-08-2003, 01:33 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM