[Switch] Winsock conflicts with Winsock2
Source: Unknown
When I was a beginner in Windows Network Programming, I encountered two types of compilation errors (102 errors are displayed in the build window of vc6). They all have some undefined or repeated definition questions, I am very depressed. The first error message is:
Error 1:Mswsock. H (69): Error c2065: 'socket ': Undeclared identifier
Error 2:Winsock2.h (99): Error c2011: 'fd _ set': 'struct 'Type redefinition
Later, I calmed down and analyzed the error message and Related Files carefully, and finally found the cause. We know that Windows network programming requires at least two header files: winsock2.h and windows. H. An old version of WinSock. h exists before winsock2.0. The order in which these three headers are included has led to the above problems. Let's take a look at the content of winsock2.h, which has the following macro definitions at the beginning of the file:
# Ifndef _ winsock2api _
# DEFINE _ winsock2api _
# DEFINE _ winsockapi _/* prevent plugin sion of WinSock. h in windows. H */
Winsock2api _ is easy to understand. This is the most common protection measure to prevent repeated inclusion of header files. _ Winsockapi _ is defined to block the old file Winsock. if the user first contains winsock2.h, it is not allowed to include Winsock. h. Otherwise, the type is repeatedly defined. How is this done? It's easy because the Winsock. h header also has the following protection measures:
# Ifndef _ winsockapi _
# DEFINE _ winsockapi _
Let's look back at winsock2.h, which is followed by the following macro commands:
/*
* Pull in windows. H if necessary
*/
# Ifndef _ inc_windows
# Include <windows. h>
# Endif/* _ inc_windows */
The function is to automatically include windows. H (_ inc_windows defined in windows. h) to define the types and constants required by winsock2.0.
Switch to Windows. h and find Winsock. We are surprised to find the following content:
# Ifndef win32_lean_and_mean
# Include <cderr. h>
# Include <DDE. h>
# Include <ddeml. h>
# Include <DLGS. h>
# Ifndef _ Mac
# Include <lzexpand. h>
# Include <mmsystem. h>
# Include <nb30.h>
# Include <rpc. h>
# Endif
# Include <shellapi. h>
# Ifndef _ Mac
# Include <winperf. h>
# If (_ win32_winnt> = 0x0400)
# Include <winsock2.h>
# Include <mswsock. h>
# Else
# Include <Winsock. h>
# Endif/* _ win32_winnt> = 0x0400 */
# Endif
// Some content is omitted here
# Endif/* win32_lean_and_mean */
See? Windows. H will reverse include winsock2.h or Winsock. H!Mutual inclusion is the source of all evil!
The following describes how the problem occurs.
Error 1:We first include winsock2.h in our project and then windows. h. If win32_lean_and_mean is not defined and _ win32_winnt is greater than or equal to 0x400, then windows. h will be automatically introduced at the beginning of winsock2.h, while windows. h will automatically introduce mswsock. h. At this time, mswsock. the socket type used in H is not yet defined, so there will be an undefined type error.
Error 2:Windows is included first. h contains winsock2.h. If win32_lean_and_mean is undefined and _ win32_winnt is undefined or its version is smaller than 0x400, then windows. h will automatically import the old Winsock. h. This will cause redefinition when winsock2.h is included.
it should be noted that the function of the macro win32_lean_and_mean is to reduce the size of Win32 header files to accelerate compilation, which is generally defined by Appwizard in stdafx. h. _ Win32_winnt is used to enable special functions in a later operating system. For example, to use a waitabletimer, the value of _ win32_winnt must be greater than or equal to 0x400. Therefore, if you have not encountered the above two problems, it is likely that you have not conducted network programming under these conditions.
the problem is not over yet. In addition to the Windows library files that come with VC, the Platform SDK of Ms also contains these header files. We can find that the Program that can be compiled well has a problem after it changes the file inclusion path in windows. The reason is simple. The windows. h file in Platform SDK is different from the file in VC. The Code in the same location is as follows:
# Ifndef win32_lean_and_mean
# Include <cderr. h>
# Include <DDE. h>
# Include <ddeml. h>
# Include <DLGS. h>
# Ifndef _ Mac
# Include <lzexpand. h>
# Include <mmsystem. h>
# Include <nb30.h>
# Include <rpc. h>
# Endif
# Include <shellapi. h>
# Ifndef _ Mac
# Include <winperf. h>
# Include <Winsock. h> // here, Winsock. H is directly included.
# Endif
# Ifndef nocrypt
# Include <wincrypt. h>
# Include <winefs. h>
# Include <winscard. h>
# Endif
# Ifndef nogdi
# Ifndef _ Mac
# Include <winspool. h>
# Ifdef inc_ole1
# Include <Ole. h>
# Else
# Include <ole2.h>
# Endif /*! Inc_ole1 */
# Endif /*! Mac */
# Include <commdlg. h>
# Endif /*! Nogdi */
# Endif/* win32_lean_and_mean */
Alas, we can't help wondering why ms is engaged in so many tricks. what's even more annoying is that since the Code is different, windows. h, but there is no macro definition that can help the program identify whether the current file is included in VC or in psdk.
Later, I wrote a specialized header file to handle winsock2.h inclusion problem, named winsock2i. h. You only need to include this file first in the source file of winsock2.0. However, due to the problem mentioned above, you need to manually define using_win_psdk when using psdk. The source code is as follows:
//
// Winsock2i. H-include winsock2.h safely.
//
// Copyleft 02/24/2005 by freefalcon
//
//
// When win32_lean_and_mean is not defined and _ win32_winnt is less than 0x400,
// If we include winsock2.h after windows. h or Winsock. H, we get some compiling
// Errors as following:
// Winsock2.h (99): Error c2011: 'fd _ set': 'struct 'Type redefinition
//
// When win32_lean_and_mean is not defined and _ win32_winnt is not less than 0x400,
// If we include winsock2.h before Windows. H, we get some other compiling errors:
// Mswsock. H (69): Error c2065: 'socket ': Undeclared identifier
//
// So, this file is used to help us to include winsock2.h safely, it shocould be
// Placed before any other header files.
//
# Ifndef _ winsock2api _
// Prevent upload sion of WinSock. h
# Ifdef _ winsockapi _
# Error header Winsock. H is wrongly ded unexpectedly.
# Endif
// Note: If you use Windows Platform SDK, you should enable following definition:
// # Define using_win_psdk
# If! Defined (win32_lean_and_mean) & (_ win32_winnt> = 0x0400 )&&! Defined (using_win_psdk)
# Include <windows. h>
# Else
# Include <winsock2.h>
# Endif
# Endif // _ winsock2api _