Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When using PInvoke, why use __stdcall?

I have been using PInvoke to let my C# application call C++ functions I wrote.

Now, I keep hearing everywhere and beyond that I need to define those externally accessible functions with the __stdcall convention. My question is: Why?

So far, I have accidentally ignored this advice, and everything works like a charm. When I add __stdcall to my functions, everything keeps working in the same way (or at least it seems so).

This article says that __stdcall is used for Win32 bit functions, but I am compiling against the x64 platform. Does that mean that I shouldn't be using __stdcall after all or does it mean that I am missing out on something else?

And please, use simple English when responding. ;-) Lines like this (quoted from the article I linked):

The callee cleans the stack, so the compiler makes vararg functions __cdecl.

make my brain feel like there's tumbleweed blowing through it.

like image 481
Lee White Avatar asked Dec 16 '22 12:12

Lee White


2 Answers

There is only one calling convention on x64 and so it does not matter which calling convention you specify. It is always ignored on x64.

On x86 it is important to make sure calling conventions match on both sides of the interface. So if you ever anticipate running your code on x86 it would be prudent to get that right now.

like image 124
David Heffernan Avatar answered Dec 29 '22 07:12

David Heffernan


Calling conventions are an historical accident in 32-bit code. There is only one convention in 64-bit code so whatever you declare doesn't matter.

If you author an unmanaged 32-bit DLL that might be used by code that wasn't written in C or C++ then declaring your exported function with __stdcall helps reduce accidents. Most language runtimes support interop to allow OS calls so they make __stdcall the default.

You'll find more details about calling conventions and name decoration in this answer

like image 20
Hans Passant Avatar answered Dec 29 '22 08:12

Hans Passant