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...
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...