I just did some real-world testing (compiling DLLs and applications with MSVC++ and MinGW, then mixing them). As it appears, I had better results with the cdecl calling convention.
More specifically: the problem with stdcall is that MSVC++ mangles names in the DLL export table, even when using extern "C". For example foo becomes _foo@4. This only happens when using __declspec(dllexport), not when using a DEF file; however, DEF files are a maintenance hassle in my opinion, and I don’t want to use them.
The MSVC++ name mangling poses two problems:
- Using
GetProcAddresson the DLL becomes slightly more complicated; - MinGW by default doesn’t prepend an undescore to the decorated names (e.g. MinGW will use
foo@4instead of_foo@4), which complicates linking. Also, it introduces the risk of seeing “non-underscore versions” of DLLs and applications pop up in the wild which are incompatible with the “underscore versions”.
I’ve tried the cdecl convention: interoperability between MSVC++ and MinGW works perfectly, out-of-the-box, and names stay undecorated in the DLL export table. It even works for virtual methods.
For these reasons, cdecl is a clear winner for me.