Thread: Please point out the obvious

  1. #1
    Registered User deoren's Avatar
    Join Date
    Mar 2003
    Posts
    63

    Question Please point out the obvious

    Hello all,

    I've recently decided to learn C++, and my lack of motivation to do so has been that I learned C first. Unfortunately I never learned it in depth, and I certainly don't know C++ in depth.

    So, yes, I'm another newbie.

    I have a program which compiles, and works, but if I use VC++ 6.0 to compile it, I get ESP errors. I've done quite a bit of looking around the net, and I keep coming back to what the compiler tells me.

    ******************************************
    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've attached the source file so everyone can see what I'm talking about.

    That's a bit cryptic for me, but some of you I'm sure it's obvious.

    Here is a couple things I do know:

    * This program properly compiles
    * This program properly executes once compiled (and linked) using DevCpp 4 or DevCpp beta 5 w/mingw32
    * The program will compile and link with MS VC++ 6.0, but will NOT execute properly.
    * I'm using URLDownloadToFile API, and LoadLibrary along with all other required functions for that concept to work.


    I originally used urlmon.lib to link with a previous project with VC++ 6.0, but I wanted to develop this application (this source file is just a small module of a larger project I'm translating, it's actually just one function) to use API calls from dlls rather than compiling using implicit linking and extra header files.

    DevCpp wouldn't compile too well with the old method. It now compiles flawlessly.

    I just don't understand everything that is going on. I really don't understand why VC 6.0 is complaining like it is.

    I apologize for the length of the post, but I'm new and a bit flustered with all of the time I've spent trying to figure it out. C++ can be kinda' daunting...

    Thanks.

    ~ DM

    If anyone can look at the attached file and give me some hints as to what's going on, I would greatly appreciate it.

    ------------------------------------------------------------------------
    As of March 14, 2003, this problem has been fixed. Download new source and/or read the following posts to see fix for problem. Thanks for everyone's help.
    Last edited by deoren; 03-14-2003 at 08:10 AM.

  2. #2
    Ecologist
    Join Date
    Aug 2001
    Location
    Utah.
    Posts
    1,291
    Try changing this:
    Code:
    (*MYPROC)(long,LPCTSTR,LPCTSTR,DWORD,long);
    to this...
    Code:
    (__stdcall * MYPROC)(long,LPCTSTR,LPCTSTR,DWORD,long);
    From what I've been able to find out about that error, the calling
    convention of your function-pointer doesn't match the calling
    convention of the function you're assigning to it... FARPROC GetProcAddress();

    FARPROC, I think, is defined as WINAPI (which is __stdcall. And
    with VC++, __cdecl is the default calling convention.)

    I don't know much, though. I'm probably wrong, and not making
    much sense. Keep in mind, I had no idea what the heck a
    calling-convention was before I decided to reply to your thread.

    But when you change it to __stdcall, the error doesn't appear.
    And that's what matters..
    Last edited by Cheeze-It; 03-09-2003 at 11:33 PM.
    Staying away from General.

  3. #3
    Registered User deoren's Avatar
    Join Date
    Mar 2003
    Posts
    63

    Cool ;-þ

    Cool.


    I just did get finished printing out the API requirements from MSDN before I checked this thread again.

    It would have taken me days to catch that if (! much >= longer) ;-)

    I did notice something that I was wondering about...


    (__stdcall * MYPROC)(long,LPCTSTR,LPCTSTR,DWORD,long);


    In the above... we're making MYPROC a pointer to ... or rather a function pointer?

    Which will pass the values (prototyped for it above?) to the function?

    I've been spending the last couple days "just getting it done" without fully grasping what I was doing. It sorta' looked right, but why I couldn't tell anyone...

    But anyway, I appreciate your response, and as you reported, it does work great. Thanks so much for taking the time to look at it.

    Oh, feel free to make any comments on the code, including better ways to do something if you wish.

    Again, thanks!

  4. #4
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Originally posted by ethic
    I don't know much, though. I'm probably wrong, and not making
    much sense. Keep in mind, I had no idea what the heck a
    calling-convention was before I decided to reply to your thread.
    Wel....your own reservations aside - your right!!!

    Windows APIS almost all use STDCALL......but C compilers default to the C calling convention..

    When you call a function, the params are copied to the stack......The main difference between the conventions is that with STDCALL, the called function wipes them off the stack....but with the C convention, the code that called the function does this right after the function returns.....so in your case, the called function didnt clean up, neither did the calling code, therefore the stack still had the params on it.....the debug version of your code checks to see that the stack is in the state it should be, and as it isnt, it asserts - creating the error

  5. #5
    Registered User deoren's Avatar
    Join Date
    Mar 2003
    Posts
    63

    Post Fixes & stdcall

    Windows APIS almost all use STDCALL......but C compilers default to the C calling convention..
    Let me show my ignorance here...
    Is STDCALL a MS calling convention Or is it a C++ calling convention?

    Also, I've updated that code, with many more comments. Maybe too many. ;-) I thought it would be worth it however for somebody to have something they can learn by.
    So if anyone wants to use it as a building block, they're welcome to.

    It uses several API calls:
    * LoadLibrary
    * GetProcAddress
    * FreeLibrary

    [All of the above are defined within windows.h]
    as well as an additional function, for which all of the others are needed to retrieve, and dispense with a .dll library to get:

    URLDownloadToFile from the urlmon.dll

    Once again, thanks for the help guys!

    ~ Deoren

  6. #6
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793

    Re: Fixes & stdcall

    Originally posted by deoren
    Let me show my ignorance here...
    Is STDCALL a MS calling convention Or is it a C++ calling convention?
    Neither...it doesnt really relate to the language employed or the vendor...its just a convention on how params are passed onto the stack and who is responsible wor taking them off

  7. #7
    Registered User deoren's Avatar
    Join Date
    Mar 2003
    Posts
    63

    Unhappy calling convention

    I'm sorry... I still don't understand.

    I understand the differences between the __stdcall and __cdecl conventions that you both talked about. Or sort of... I understand at least that there is a difference.

    Are you saying it's how the program acts once it's been converting to machine code... or ...

    I'm lost here...
    Last edited by deoren; 03-16-2003 at 08:01 PM.

  8. #8
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793

    Re: calling convention

    Originally posted by deoren
    I'm sorry... I still don't understand.

    I understand the differences between the __stdcall and __cdecl conventions that you both talked about. Or sort of... I understand at least that <I>there is</I> a difference.

    Are you saying it's how the program acts once it's been converting to machine code... or ...

    I'm lost here...
    Yes, its on a machine code level......so its not something you need to worry about...only be aware of

    Code:
    #include <iostream>
    
    
    void _cdecl Hello1(const char* szBuff)
    //force C calling convention
    {
    	std::cout << szBuff << std::endl;
    }
    
    void _stdcall Hello2(const char* szBuff)
    //force STDCALL calling convention
    {
    	std::cout << szBuff << std::endl;
    }
    
    int main()
    {
    	const char* szBuff = "Hello World";
    
    	__asm
    	{
    		push szBuff //push the param onto the stack
    		call Hello1 //call the function
    		add esp,4 //restore the stack to previous state
    
    		push szBuff //push the param onto the stack
    		call Hello2 //call the function
    		//dont restore stack as Hello2 will do that
    	}
    	
    	return 0;
    }

  9. #9
    Registered User deoren's Avatar
    Join Date
    Mar 2003
    Posts
    63

    Smile I'm getting it...

    Cool. That's making a lot more sense. So it's a way to implement in C++, what's actually going on at a lower level, right? So basically when you say it's not a particular language convention, you're saying that it's the way that any language works with the stack?

    Forgive me if I'm assuming too much...

    Also, what does the
    Code:
     add esp,4
    do? How does it set the stack back to normal? When you called the function by C calling conventions, does it alter the stack by 4? Such as taking 4 away?

    BTW, I really appreciate you taking time to reply to my posts. I feel like I'm getting a lot out of them!

  10. #10
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Ok...in my code above I push a 4 byte value (actually a 32bit pointer to a string) onto the stack....the stack pointer is held in the ESP register for Intel type chips...tht register is decreased 4 bytes as you have added 4 bytes to the stack....after this param is no longer needed, the ADD instruction increases the ESP register by 4 (bytes) therefore returning the stack position to the same place before the CALL

  11. #11
    Registered User deoren's Avatar
    Join Date
    Mar 2003
    Posts
    63

    Lightbulb Ah!

    Makes perfect sense. Thanks for your paitence. ;-)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help realy needed
    By ZohebN in forum C++ Programming
    Replies: 2
    Last Post: 04-08-2008, 09:37 AM
  2. Getting a floating point exception
    By SnertyStan in forum C Programming
    Replies: 13
    Last Post: 03-25-2008, 11:00 AM
  3. How to monitor process creation?
    By markiz in forum Windows Programming
    Replies: 31
    Last Post: 03-17-2008, 02:39 PM
  4. instantiation point discussion
    By George2 in forum C++ Programming
    Replies: 1
    Last Post: 03-08-2008, 03:48 AM
  5. overloading operator help
    By syrel in forum C++ Programming
    Replies: 8
    Last Post: 09-30-2004, 10:49 AM