Greetings,
I have just noticed something interesting about the CLR's generation of
stub code for p/invoke calls (this is on .NET 2.0):
I am using a library called Cairo for some vector graphics drawing.
On windows, it's a DLL written in plain C, exporting its functions as
CDECL.
To interface with my C# app, I found a managed wrapped called "cairo-
sharp", which seems to work quite well.
The interesting thing is, the wrapper code (also C#) uses DllImport in
its default manner, that is; implicitly setting CallingConvention to
CallingConvention.Stdcall instead of CallingConvention.Cdecl, which
should be used for a CDECL DLL.
Now what _should_ happen is that the stack wouldn't get cleaned up after
a call into the DLL, since my code is assuming STDCALL (callee cleans
stack), and the DLL is using CDECL (caller cleans stack).
However, looking at the stack pointer before and after calls through the
wrapper everything is fine!
Tracing lower into the guts of the CLR using windbg, I seem to be seeing
that the generated stub code is fixing up the stack after the call to the
native DLL even though I didn't ask it to!
So it seems like the CLR auto-detects the calling convention of native
libraries (at least in some cases) and fixes the programmers mistakes.
This is definitely not specified anywere in the documentation..
What gives?
- A.A.
Ben Voigt [C++ MVP] - 16 Jun 2007 21:53 GMT
> Greetings,
>
[quoted text clipped - 29 lines]
> This is definitely not specified anywere in the documentation..
> What gives?
The only thing I can think of is that the name mangling (C-style, not C++)
is sufficiently different (cdecl uses leading underscore, stdcall is
trailing "@N") for p/invoke to detect what's up. Or perhaps it is simply
restoring the stack for all calls, just to be safe.
> - A.A.
Alfonso Almazor - 16 Jun 2007 22:24 GMT
>> Greetings,
>>
[quoted text clipped - 37 lines]
>
>> - A.A.
Quite.
I suppose I was hoping that this behavior is actually documented
somewhere.
I don't like the CLR doing automagic things like this without being asked
to :)
- A.A.
Robert Simpson - 17 Jun 2007 04:13 GMT
> Greetings,
>
[quoted text clipped - 29 lines]
> This is definitely not specified anywere in the documentation..
> What gives?
It's always done this. I think its just part of the overhead of P/Invoke
that it records and fixes up the stack pointer before and after a call.
Robert