Re: StdCall vs. CDecl



Hello Bob,

Apart from Jeroen's inputs, I'd like to add my ideas of this issue.

First, let's look at the pure native world (without .NET).

__stdcall means that the function itself will remove the args from the
stack. __cdecl means that the caller needs to remove the args. If you call
a __cdecl function as __stdcall, it means that the function will expect the
caller to clean up the stack, while the caller will expect the function to
clean up the stack. This means that nobody will clean up the stack.

(It's like two roommates that each believe that the other is going to pay
the rent bill. This will result in the rent not being paid (unless there
happened to be no rent due that month) with equally bad consequences.)

This will work if the function takes no arguments (nothing to clean up), or
if immediately after the function returns, the next thing happens to be
something that "autofixes" the stack (e.g., the caller immediately returns
to its caller and uses something like EBP to restore its stack frame (so
the current value of ESP doesn't matter). This is exceedingly fragile.

[If you call a __stdcall function as __cdecl, it means that the function
will clean up the stack and then the caller will also cleanup the stack,
resulting in too much being removed from the stack with equally disastrous
consequences.]

Now, why does our VB.NET code work well when the calling convention
mismatches?

This is because the .NET interop layer is able (to a certain extend) to fix
the calling convention mismatches. See:
http://msdn.microsoft.com/en-us/library/ms998551.aspx

The RCW is responsible for marshaling parameters as execution flow
transitions between managed code and unmanaged code. Calling into unmanaged
COM code from managed code is made easy by the CLR; however, it carries a
performance cost. The following steps are performed:
Perform data marshaling.
*Fix the calling convention.*
Protect callee-saved registers.
Switch thread mode to ensure that the garbage collector does not block
unmanaged threads.
Erect an exception-handling frame on calls into unmanaged code.
Optionally take control of the thread.

Though this article is for COM-.NET Interop, the work of "fixing the
calling convention" is done by CLR. However, we'd better change our code so
the caller matches the callee, otherwise, there may be some performance
problems.

Please let me know if you have any other concerns, or need anything else.

P.S.
Bob, I sent another letter to your email box yesterday, to illustrate the
differences between the calling conventions. Have you received it? I am not
able to paste the comparison in newsgroup because it contains some rich
texts.

Regards,
Jialiang Ge (jialge@xxxxxxxxxxxxxxxxxxxx, remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
msdnmg@xxxxxxxxxxxxxx

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================

.



Relevant Pages

  • Re: ctypes with Compaq Visual Fortran 6.6B *.dll (Windows XP), passing of integer and real values
    ... cdll is for importing functions which use the cdecl calling convention ... where the caller must clean up the stack. ... function that is called is responsible for cleaning up the stack. ... The error message was telling you that ctypes pushed 4 bytes of argument ...
    (comp.lang.python)
  • Re: DirectX in HLA
    ... > stuff stdcall like the usual API? ... you don't want to clean the ... > stack. ... If it's C calling convention, ...
    (comp.lang.asm.x86)
  • Re: DirectX in HLA
    ... > stuff stdcall like the usual API? ... you don't want to clean the ... > stack. ... If it's C calling convention, ...
    (alt.lang.asm)
  • Re: Is it possible to use the value of the PROGRAM ID within the source code?
    ... Every called program has a way of returning to its caller. ... >information about calling history in some sort of hardware stack? ... True but discordant with the culture of operating systems and other languages. ... premise is that called programs may irrationally corrupt parameter values. ...
    (comp.lang.cobol)
  • Re: Stack Overflow
    ... Sub Caller() ... '<<< COMPILER STORES THIS LOCATION ... Sub CalledFunction() ... (Think of it like a stack of plates. ...
    (microsoft.public.excel.programming)