今天写一个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>一开始,就有有这么几条指令
原来就是它了…
可能还不明白,那么,请看<winsock.h>中一开始的这几条指令
上面的方法2之所以能成功,就是因为当你先引用了<winsock2.h>的时候,就会#define _WINSOCKAPI_
当你之后引用<winsock.h>,就会因为此时已经"定义"了 _WINSOCKAPI_而直接跳到<winsock.h>的文件尾,相当于<winsock.h>就没有被包含
附加一句,winsock2.h中有这么一段:
所以,在#include<winsock2.h>以后,其实可以不用再#include<windows.h>了