windows.h与winsock2.h的包含顺序

大凡在Windows平台下用C++做网络开发很多时候都会同时包含这两个头文件,如若顺序不当(windows.h先于winsock2.h)就会出现很多莫名其妙的错误。诸如:

警告    4    warning C4005: “AF_IPX”: 宏重定义    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    91
警告    5    warning C4005: “AF_MAX”: 宏重定义    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    127
警告    6    warning C4005: “SO_DONTLINGER”: 宏重定义    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    163
错误    7    error C2011: “sockaddr”: “struct”类型重定义    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    206
错误    8    error C2143: 语法错误 : 缺少“}”(在“常量”的前面)    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    384
错误    9    error C2143: 语法错误 : 缺少“;”(在“常量”的前面)    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    384
错误    10    error C2059: 语法错误 : “常量”    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    384
错误    11    error C2143: 语法错误 : 缺少“;”(在“}”的前面)    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    437
错误    12    error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    437
错误    13    error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    437
警告    14    warning C4005: “IN_CLASSA”: 宏重定义    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    518
警告    15    warning C4005: “IN_CLASSB”: 宏重定义    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    524
警告    16    warning C4005: “IN_CLASSC”: 宏重定义    c:\program files\microsoft sdks\windows\v6.0a\include\ws2def.h    530
……
错误    133    fatal error C1003: 错误计数超过 100;正在停止编译    f:\yang fan\courses\works\c++\mylamebt\btendpoint\btendpoint.h    267

初看到如此一堆的错误委实不爽,但是只要将二者的包含顺序调换一下问题就会解决,原因参见下面那个链接。另外,上述问题不仅影响直接包含二者的文件,还影响间接包含的情形。比如,a.h包含了windows.h,b.h包含了winsock2.h,如果在c.h当中要引用a.h和b.h,那么正确的顺序应当是b.h先于a.h。当然,实践当中有时很难找到究竟是哪两个文件顺序不对了,终极的解决办法是,在当前工程(就是编译不过的这个工程)所有include语句最前面加上#include <winsock2.h>和#include<windows.h>,世界清静了。

http://blog.chinaunix.net/u2/64540/showart_689402.html

为防止链接失效,敬录如下:

关于WINSOCK.H与winsock2.h中的重定义解决办法分析
问题描述:在 VC 6.0中使用socket相关的函数时没有什么问题,可是到了.net下就有以下类似的错误,
[C++ Error] winsock2.h(109): E2238 Multiple declaration for 'fd_set'
[C++ Error] winsock.h(54): E2344 Earlier declaration of 'fd_set'
[C++ Error] winsock2.h(112): E2146 Need an identifier to declare
[C++ Warning] winsock2.h(144): W8017 Redefinition of 'FD_SET' is not identical
[C++ Error] winsock2.h(153): E2238 Multiple declaration for 'timeval'
[C++ Error] winsock.h(97): E2344 Earlier declaration of 'timeval'
[C++ Error] winsock2.h(209): E2238 Multiple declaration for 'hostent'
[C++ Error] winsock.h(153): E2344 Earlier declaration of 'hostent'
[C++ Error] winsock2.h(222): E2238 Multiple declaration for 'netent'
[C++ Error] winsock.h(166): E2344 Earlier declaration of 'netent'
[C++ Error] winsock2.h(229): E2238 Multiple declaration for 'servent'
[C++ Error] winsock.h(173): E2344 Earlier declaration of 'servent'
[C++ Error] winsock2.h(241): E2238 Multiple declaration for 'protoent'
[C++ Error] winsock.h(185): E2344 Earlier declaration of 'protoent'
[C++ Error] winsock2.h(327): E2238 Multiple declaration for 'in_addr'
[C++ Error] winsock.h(269): E2344 Earlier declaration of 'in_addr'
[C++ Error] winsock2.h(385): E2238 Multiple declaration for 'sockaddr_in'
[C++ Error] winsock.h(319): E2344 Earlier declaration of 'sockaddr_in'
[C++ Error] winsock2.h(395): E2238 Multiple declaration for 'WSAData'
[C++ Error] winsock.h(329): E2344 Earlier declaration of 'WSAData'
[C++ Error] winsock2.h(411): E2146 Need an identifier to declare
[C++ Warning] winsock2.h(455): W8017 Redefinition of 'SO_DONTLINGER' is not identical
[C++ Warning] winsock2.h(512): W8017 Redefinition of 'AF_IPX' is not identical
[C++ Warning] winsock2.h(540): W8017 Redefinition of 'AF_MAX' is not identical
[C++ Error] winsock2.h(546): E2238 Multiple declaration for 'sockaddr'
[C++ Error] winsock.h(492): E2344 Earlier declaration of 'sockaddr'
[C++ Error] winsock2.h(586): E2238 Multiple declaration for 'sockproto'
[C++ Error] winsock.h(501): E2344 Earlier declaration of 'sockproto'
[C++ Error] winsock2.h(625): E2238 Multiple declaration for 'linger'
[C++ Error] winsock2.h(625): E2228 Too many error or warning messages

Solution:

This problem arises because windows.h (at least, that version of it) includes not winsock2.h but winsock.h; sadly when Microsoft wrote winsock2.h they chose neither to change windows.h to include winsock2.h, which replaces winsock.h, nor to include windows.h from winsock2.h and then add the definitions for the new Winsock 2 API methods & structures (this might seem reasonable since Winsock 2 does, strictly speaking, replace Winsock 1, but since the API must be fully backwards-compatible the distinction is somewhat meaningless and there's no real benefit to making winsock2.h standalone).

The fix is thankfully simple: always "#include <winsock2.h>" before windows.h.

However, you must remember that if windows.h has been included by (for example) a higher-level header file that is subsequently including your header file, it's too late - so you must make sure that the higher-level header files respect this convention also.

It is however rarely necessary to modify the header files of libraries or other code modules you are using just because you include their header files, and their header files include windows.h - you can just include winsock2.h before you include the library's header files.


在包含jrtplib有时候我也遇到这个问题,解决方法与之相同。一句话,在#include<windows.h>之前 #include <winsock2.h> 问题就可以解决。

问题描述]
   在包含了<windows.h>以及<winsock2.h>的工程中,编译有时会出现如
下错误:

     error C2011: 'fd_set' : 'struct' type redefinition
     error C2011: 'timeval' : 'struct' type redefinition
                     ....
     error C2375: 'accept' : redefinition; different linkage
[原因分析]
   主要原因是因为<windows.h>中包含了<winsock.h>头文件,由于其版
本的不同,导致出
现上述的错误。<windows.h>中相关代码如下:
               #ifndef WIN32_LEAN_AND_MEAN
               #include <cderr.h>
               #include <dde.h>
               #include <ddeml.h>
               ........
                #ifndef _MAC
               #include <winperf.h>
               #include <winsock.h>
               #endif
                .......

               #include <commdlg.h>
               #endif
               #endif
[解决方案]
    由以上代码可以看出如果在没有定义WIN32_LEAN_AND_MEAN宏
的大前
提下windows.h有可能包含winsock.h 头文件,因此我们得出一个很简单
的解决方
法就是在包含<windows.h>之前定义WIN32_LEAN_AND_MEAN宏,如
下所示:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

posted @ 2009-10-14 12:00  tonyyang132  阅读(16738)  评论(1编辑  收藏  举报