error C2011: “sockaddr”:“struct”类型重定义
error C2011: “sockaddr”:“struct”类型重定义
这个问题的出现主要伴随着包含 Windows.h 的文件. 打开 Windows.h 这个文件. 有这样一段.
#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>
#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 */
我们看到如果没有定义 WIN32_LEAN_AND_MEAN, 且也没有定义 _MAC, 则会加载 winsock.h
而 winsock.h 中有 sockaddr 结构的定义:
/*
* Structure used by kernel to store most
* addresses.
*/
struct sockaddr {
u_short sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};
而 ws2def.h 中也有 sockaddr 结构的定义
//
// Structure used to store most addresses.
//
typedef struct sockaddr {
#if (_WIN32_WINNT < 0x0600)
u_short sa_family;
#else
ADDRESS_FAMILY sa_family; // Address family.
#endif //(_WIN32_WINNT < 0x0600)
CHAR sa_data[14]; // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
WinSock2.h 在必要情况下会包含进 Windows.h
/*
* Pull in WINDOWS.H if necessary
*/
#ifndef _INC_WINDOWS
#include <windows.h>
#endif /* _INC_WINDOWS */
此外它引入了 ws2def.h,
#include <ws2def.h>
因此, 解决冲突的办法是仅使用其中一种定义. 一般现在不使用 winsock.h. 故在项目中凡是 #include <Windows.h> 的地方, 在前面加上 #define WIN32_LEAN_AND_MEAN
注: 以我的电脑为例,
Windows.h 所在文件夹一般为 C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um
ws2def.h 所在文件夹为 C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared
winsock.h 和 WinSock2.h 均位于C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um