Log in

View Full Version : MSVCRT.DLL and _beginthreadex()


LoRd_MuldeR
21st October 2012, 17:48
I have a question for the C/C++ developers:

I'm working on a small plug-in and I'm using "MSVCRT.DLL", i.e. the variant of the CRT that is part of Windows itself and doesn't need to be installed as a redistributable. Sure, I could just use the CRT of the current Visual Studio and link it in statically, but that would bloat the plug-in too much. So, I'm using "MSVCRT.DLL" instead of "MSVCRT??.DLL" and this all works fine so far, once I managed to obtain the required import libs. After all, MinGW does the very same thing.

Unfortunately I'm a bit confused about _beginthreadex(), because it's definition changed between Visual Studio 2008 and Visual Studio 2010. The specs from Visual Studio 2005 and 2008 (http://msdn.microsoft.com/de-de/library/kdzttdcb%28v=vs.90%29.aspx) say that the thread function, i.e. the thread entry point, is __cdecl (or more specifically, the calling convention isn't specified explicitly, so it defaults to __cdecl, obviously):
uintptr_t _beginthreadex(
void *security,
unsigned stack_size,
unsigned ( *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);

Starting with Visual Studio 2010 (http://msdn.microsoft.com/de-de/library/kdzttdcb%28v=vs.100%29.aspx) this changed to __stcall, to better match CreateThread() from the Win32 API:
uintptr_t _beginthreadex( // NATIVE CODE
void *security,
unsigned stack_size,
unsigned ( __stdcall *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);

These specs refer to the "MSVCRT??.DLL" of each version of Visual Studio, but what is the correct way to call _beginthreadex() from the MSVCRT.DLL that is independent from Visual Studio ???

Did they really change the calling convention or did they just correct the documentation with Visual Studio 2010? And if they changed it, did it also change in MSVCRT.DLL? Might it even be different between different Windows Versions? :eek:

Any advice would be greatly appreciated. And yes, I know it should be simple to find out the "correct" calling convention by reading the Assembly of MSVCRT.DLL, but I'm not good at x86 Assembly ;)

:thanks:


[EDIT]

Actually it seems the remarks below contradict their own code excerpt:
The routine at start_address passed to _beginthreadex must use the __stdcall calling convention...

And that's from the Visual Studio 2008 specs !!!

If I declare _beginthreadex() like the code given in the Visual Studio 2008 specs, it certainly won't compile with a thread-function that uses __stdcall, because it will expect __cdecl :rolleyes:

How does this go together ???


[EDIT 2.0]

Does anybody happen to have Visual Studio 2008 or even better Visual Studio 2005 installed and can tell my how _beginthreadex() was declared in the actual code?

I now believe the code excerpt in the specs must simply be wrong and the calling convention was __stdcall in Visual Studio 2005/2008 too...

MasterNobody
21st October 2012, 19:02
LoRd_MuldeR
_beginthreadex() in contrast to _beginthread() always use __stdcall calling convention. If you see something different it is probably error in documentation but even MSDN for Visual Studio .NET 2003 tells that it should be __stdcall: _beginthread, _beginthreadex (http://msdn.microsoft.com/en-us/library/kdzttdcb%28v=vs.71%29.aspx)

P.S. Probably this error in MSDN is only in DE version. English version is correct (hm. may be except Visual Studio 2005).

LoRd_MuldeR
21st October 2012, 19:17
MasterNobody, thank you for confirming! :)

BTW: I was looking at the English version of the specs. And the specs for Visual Studio 2005/2008 definitely differ from those for Visual Studio .NET 2003 or Visual Studio 2010 (the latter two agree on __stdcall though).