项目中一些宏冲突定义问题(Windows.h和WinSock2.h)

遇到的问题

在编译时项目中出现大量重复定义错误,或者符号...未找到,经百度发现原因是同时包含了Windows.h和Winsock2.h。

分析

其实是一个顺序问题,我们应该确保先定义Winsock2.h再定义Windows.h,因为在Windows.h中有这样一段代码

#ifndef _MAC
#include 
#include     //重点!!!
#endif

它包含了winsock.h,而我们打开winsock.h,它第一句话就定义了宏

#ifndef _WINSOCKAPI_
#define _WINSOCKAPI_

所以如果我们包含了Windows.h,就会定义WINSOCKAPI这个宏,下面继续看Winsock2.h,它第一句话是这样定义宏的

#ifndef _WINSOCK2API_
#define _WINSOCK2API_
#define _WINSOCKAPI_   /* Prevent inclusion of winsock.h in windows.h */

而我们显然还没有定义WINSOCK2API,所以我们j继续往下在这里就会重复定义宏WINSOCKAPI,导致报错,而且官方文档里也明确说明了禁止winsock.h纳入windows.h,这种相互包含就是万恶之源。

如果反过来定义便不会出现这种情况,先包含Winsock2.h则先定义了宏WINSOCKAPI,等到Windows.h时就不会再重复定义。

解决方法

综上,我们要确保进行Winsock2.h先被定义,即接收如下顺序

#include 
#include 

具体到我们的项目,常用到的,在UdpConnection.h和seeker/socketUtil.h中直接或间接定义了Winsock2.h,在seeker/loggerApi.h间接定义了Windows.h,所以我们要确保UdpConnection.h和seeker/socketUtil.h定义在seeker/loggerApi.h之前,但是为了保险,建议大家把UdpConnection.h和seeker/socketUtil.h都定义在最开始,因为我在使用时如果把定义在UdpConnection.h之后也会报同样的错,我没找到asio.hpp中具体的相关宏定义位置,但我相信应该也是这个原因导致的。

一点补充

在Windows下如果定义了,使用algorithm里面的std::max函数时也会出现定义冲突,有个小技巧,加个括号可以阻止宏替换。

 

你可能感兴趣的:(c++)