您的位置:首页 > 其它

'fd_set' redefinition winsock2.h,相关头文件条件编译处理

2009-10-29 20:49 567 查看
今天写一个TCP/IP的小程序的时候,偶然间发现一个错误

工程类型:Win32 Console Application

错误如下:

--------------------Configuration: TcpSer - Win32 Debug--------------------
Compiling...
main.cpp
d:/program files/microsoft visual studio/vc98/include/winsock2.h(99) : error C2011: 'fd_set' : 'struct' type redefinition
d:/program files/microsoft visual studio/vc98/include/winsock2.h(134) : warning C4005: 'FD_SET' : macro redefinition
d:/program files/microsoft visual studio/vc98/include/winsock.h(83) : see previous definition of 'FD_SET'

.....

.....

TcpSer.exe - 65 error(s), 11 warning(s)

一看的我就头大了,怎么可能会报错呢?

看了看错误原因,可能是因为winsock.h和winsock2.h中有重定义的部分

从网上随便搜了搜,也有说到解决办法的,两种方式:

1、在引用<windows.h>之前,加上预处理指令:#define WIN32_LEAN_AND_MEAN ,其实,这也是VS预编译头stdafx.h中使用到的一条指令。

2、就是在引用<windows.h>之前,引用<winsock2.h>

用了以后,当然,问题是解决了,但是,为什么呢?

对于方法一奏效的原因:有不妥之处,下面有讲解

打开<winsock2.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>

#if(_WIN32_WINNT >= 0x0400)
#include <winsock2.h>
#include <mswsock.h>

#else
#include <winsock.h>
#endif /* _WIN32_WINNT >= 0x0400 */

如果,你直接#define WIN32_LEAN_AND_MEAN_,那么,中间有的那些所有的#include的头文件都将没有被引入(虽然说它们不一定会被用到),但是这当然是不妥的。

所以,此时应该将#define WIN32_LEAN_AND_MEAN_改成#define _WIN32_WINNT 0x0400(或者大于0x0400的值)

这时候,就只会将一条#include<winsock.h>指令排除掉,其他的都没有影响。

对于方法二奏效的原因:

于是,我将3个头文件<windows.h>,<winsock.h>,<winsock2.h>文件打开看了看,

发现,在<winsock2.h>一开始,就有有这么几条指令

#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */
...
...
#endif   /* _WINSOCK2API_ */   //文件结尾


原来就是它了…

可能还不明白,那么,请看<winsock.h>中一开始的这几条指令

#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_
....
....
#endif  /* _WINSOCKAPI_ */     //文件结尾


上面的方法2之所以能成功,就是因为当你先引用了<winsock2.h>的时候,就会#define _WINSOCKAPI_

当你之后引用<winsock.h>,就会因为此时已经"定义"了 _WINSOCKAPI_而直接跳到<winsock.h>的文件尾,相当于<winsock.h>就没有被包含

附加一句,winsock2.h中有这么一段:

/*
* Pull in WINDOWS.H if necessary
*/
#ifndef _INC_WINDOWS
#include <windows.h>
#endif /* _INC_WINDOWS */


所以,在#include<winsock2.h>以后,其实可以不用再#include<windows.h>了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐