The chBEGINTHREADEX Macro

[Previous] [Next]

All the multithreaded samples in this book use the _beginthreadex function, which is in Microsoft's C/C++ run-time library, instead of the operating system's CreateThread function. I use _beginthreadex because it prepares the new thread to use the C/C++ run-time library functions and ensures that the per-thread C/C++ run-time library information is destroyed when the thread returns. (See Chapter 6 of Programming Applications for Microsoft Windows, Fourth Edition, for more details.) Unfortunately, the _beginthreadex function is prototyped as follows:

 unsigned long __cdecl _beginthreadex(    void *,    unsigned,    unsigned (__stdcall *)(void *),     void *,     unsigned,     unsigned *); 

Although the parameter values for _beginthreadex are identical to the parameter values for the CreateThread function, the parameters' data types do not match. Here is the prototype for the CreateThread function:

 typedef DWORD (WINAPI *PTHREAD_START_ROUTINE)(PVOID pvParam); HANDLE CreateThread(    PSECURITY_ATTRIBUTES  psa,     DWORD                 cbStack,    PTHREAD_START_ROUTINE pfnStartAddr,     PVOID                 pvParam,    DWORD                 fdwCreate,     PDWORD                pdwThreadId); 

Microsoft did not use the Windows data types when creating the _beginthreadex function's prototype because Microsoft's C/C++ run-time group does not want to have any dependencies on the operating system group. I commend this decision; however, this makes using the _beginthreadex function more difficult.

There are really two problems with the way Microsoft prototyped the _beginthreadex function. First, some of the data types used for the function do not match the primitive types used by the CreateThread function. For example, the Windows data type DWORD is defined as follows:

 typedef unsigned long DWORD; 

This data type is used for CreateThread's cbStack parameter as well as for its fdwCreate parameter. The problem is that _beginthreadex prototypes these two parameters as unsigned, which really means unsigned int. The compiler considers an unsigned int to be different from an unsigned long and generates a warning. Because the _beginthreadex function is not a part of the standard C/C++ run-time library and exists only as an alternative to calling the CreateThread function, I believe that Microsoft should have prototyped _beginthreadex this way to avoid generating warnings:

 unsigned long __cdecl _beginthreadex(    void                   *psa,     unsigned               long cbStack,    unsigned (__stdcall *) (void *pvParam),     void                   *pvParam,    unsigned long          fdwCreate,     unsigned long          *pdwThreadId); 

The second problem is just a small variation of the first. The _beginthreadex function returns an unsigned long representing the handle of the newly created thread. An application typically wants to store this return value in a data variable of type HANDLE as follows:

 HANDLE hThread = _beginthreadex(...); 

This code causes the compiler to generate a warning. To avoid the compiler warning, you must rewrite the line, introducing a cast as follows:

 HANDLE hThread = (HANDLE) _beginthreadex(...); 

But this is inconvenient. To make life a little easier, I defined a chBEGINTHREADEX macro in CmnHdr.h to perform all of this casting for me:

 typedef unsigned (__stdcall *PTHREAD_START) (void *); #define chBEGINTHREADEX(psa, cbStack, pfnStartAddr, \    pvParam, fdwCreate, pdwThreadId)                 \       ((HANDLE)_beginthreadex(                      \          (void *)        (psa),                     \          (unsigned)      (cbStack),                 \          (PTHREAD_START) (pfnStartAddr),            \          (void *)        (pvParam),                 \          (unsigned)      (fdwCreate),               \          (unsigned *)    (pdwThreadId)))  



Programming Server-Side Applications for Microsoft Windows 2000
Programming Server-Side Applications for Microsoft Windows 2000 (Microsoft Programming)
ISBN: 0735607532
EAN: 2147483647
Year: 2000
Pages: 126

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net