Boost::asio winsock 和 winsock 2 兼容性问题
Posted
技术标签:
【中文标题】Boost::asio winsock 和 winsock 2 兼容性问题【英文标题】:Boost::asio winsock and winsock 2 compatibility issue 【发布时间】:2012-04-02 18:26:02 【问题描述】:我的项目使用 windows.h,其中使用了 winsock.h,我需要包含使用 winsock2 的 boost:assio。所以我收到很多错误,说 Winsock.h 已经包含在内。 我可以定义 WIN32_LEAN_AND_MEAN。这样windows.h就不会使用winsock。问题是,我需要 windows.h 才能使用它,而异步计时器只需要 Asio。我不需要它的 winsock2.h 。我尝试搜索如何禁用它的 winsock2 使用,我发现我可以通过在包含 boost:asio 之前定义 BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN 来做到这一点,但我仍然得到同样的错误。
#include <windows.h>
#define BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN
#include <boost/asio.hpp>
错误
1>c:\program files\boost\boost_1_47\boost\asio\detail\socket_types.hpp(22): 致命错误 C1189: #error : WinSock.h 已经包含
【问题讨论】:
【参考方案1】:尝试更改包含的顺序。以boost/asio.hpp
开头,后面加上windows.h
。
通常任何代码库的编写者都会解决兼容性问题,但如果他们的代码首先满足编译器和预处理器,他们可以做得更好。
ACE 也有类似的问题,包括 ace/OS.h
,然后才解决它。
【讨论】:
还有一个问题:一个应用程序是否可以从另一个应用程序读取带有 winsock2 的数据包,女巫发送带有 winsock1 的数据包?反之亦然。 @DainiusKreivys 我不确定从 winsock1 到 2 的更新是什么。我只能猜测它主要是错误修复。除了错误,一切都应该可以正常工作,但是由于可能存在错误,它们可能会出现。 更改包含的顺序并没有真正解决问题,只是将其从错误更改为警告。【参考方案2】:正如 Danius(OP)指出的那样编译
#include <windows.h>
#include <boost/asio.hpp>
失败并出现此错误:
1>c:\source\<SNIP>\boost\1.51.0\boost\asio\detail\socket_types.hpp(22): fatal error C1189: #error : WinSock.h has already been included
另一方面
#include <boost/asio.hpp>
#include <windows.h>
产生一堆噪音并错误设置Windows版本#
1? Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:
1> - add -D_WIN32_WINNT=0x0501 to the compiler command line; or
1> - add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.
1> Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
我找不到任何不会留下不好味道的方法,但是:
#ifdef _WIN32
# ifdef USE_ASIO
// Set the proper SDK version before including boost/Asio
# include <SDKDDKVer.h>
// Note boost/ASIO includes Windows.h.
# include <boost/asio.hpp>
# else // USE_ASIO
# include <Windows.h>
# endif // USE_ASIO
#else // _WIN32
# ifdef USE_ASIO
# include <boost/asio.hpp>
# endif // USE_ASIO
#endif //_WIN32
确实会产生干净的编译。
应该没那么难社论>
【讨论】:
请说明“this”应该在哪里更改 把它放在一个头文件中,否则你可能会在包含头文件的 cpp 文件中包含 asio.hpp 和 windows.h 和 #define USE_ASIO。#include <SDKDDKVer.h>
是最终帮助我克服这一切的缺失的想法。谢谢!【参考方案3】:
对我来说,切换包含的顺序会导致与我正在使用的另一个 Microsoft 包含的编译错误 - 使用“typedef 接口”声明事物。
由于我的错误来自 socket_types.h,因此来自以下几行:
# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
# error WinSock.h has already been included
# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
我在windows.h之前加上了“winsock2.h”的include,最后是boost/asio.hpp include,然后就顺利编译了。
【讨论】:
【参考方案4】:#ifdef BOOST_OS_WINDOWS
#define _WIN32_WINNT 0x0501
#if _WIN32_WINNT <= 0x0501
#define BOOST_ASIO_DISABLE_IOCP
#define BOOST_ASIO_ENABLE_CANCELIO
#endif
#endif
【讨论】:
通常被认为是解释您的建议/答案的好方法。即使在技术上是正确的,仅代码的答案也可能会令人惊讶地缺乏信息。【参考方案5】:我使用的另一个解决方法是集中所有依赖于 asio 的 XXX.hpp 文件中的代码并将其包含在实现的每个窗口的顶部 XXX.cpp 文件,您可以在其中使用其对象。
此方法将包含 asio 置于任何其他包含 windows.h 之上并解决问题。
【讨论】:
以上是关于Boost::asio winsock 和 winsock 2 兼容性问题的主要内容,如果未能解决你的问题,请参考以下文章
使用 Boost.Asio 和 OpenSSL 的 HTTPS 请求