Boost::asio中的winsock和winsock 2兼容性问题

28

我的项目使用了windows.h,其中也用到了winsock.h,而我需要包含boost:asio,它使用的是winsock2.h。因此我得到了许多错误,提示Winsock.h已经被包含了。 我可以定义WIN32_LEAN_AND_MEAN来避免windows.h使用winsock。但问题是,我需要windows.h来使用它,我只需要Asio来实现异步定时器,不需要它的winsock2.h。我尝试搜索如何禁用Asio对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 已经被包含

5个回答

32

尝试改变包含的顺序。以boost/asio.hpp开始,然后再放windows.h

通常情况下,任何代码库的编写者都会解决兼容性问题,但如果他们的代码首先遇到编译器和预处理器,那么他们可以更好地解决问题。

ACE也存在类似的问题,将ace/OS.h放在其他内容之前可以解决它。


还有一个问题:一个应用程序能否从另一个使用winsock1发送数据包的应用程序中读取使用winsock2发送的数据包?反之亦然。 - Dainius Kreivys
@DainiusKreivys 我不确定从winsock1到2进行了哪些更新。我只能猜测主要是修复了错误。除了错误之外,一切应该正常工作,但由于可能存在错误,它们可能会出现。 - selalerer
更改包含的顺序并没有真正解决问题,只是将其从错误变为警告。 - Dale Wilson

17

正如Danius(楼主)所指出的,编译时

#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

能够生成干净的编译结果。

<EDITORIAL>这本应该不难 </EDITORIAL>


请指出应更改“此处”的位置。 - IceFire
将此内容放入头文件中,您可能会在其中包含asio.hpp和windows.h,并在包含头文件的cpp文件中#define USE_ASIO。 - Dale Wilson
#include <SDKDDKVer.h> 这个想法的确帮助我克服了所有问题。谢谢! - pestophagous

14

对我来说,改变包含文件的顺序会导致我正在使用的另一个微软包含文件编译错误 - 它正在使用“typedef interface”声明。

由于我的错误来自socket_types.h,具体来自以下代码:

# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
#  error WinSock.h has already been included
# endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)

我在Windows.h之前放置了“winsock2.h”的引用,最后再引用boost/asio.hpp,然后编译顺利通过。


0
另一个我使用的解决方法是将所有依赖asio的代码集中在一个XXX.hpp文件中,并在每个实现XXX.cpp文件的顶部包含它,以便在使用其对象时使用。
这种方法将asio的包含放置在任何其他包含windows.h之上,并解决了问题。

0
#ifdef BOOST_OS_WINDOWS
#define _WIN32_WINNT 0x0501
#if _WIN32_WINNT <= 0x0501
#define BOOST_ASIO_DISABLE_IOCP
#define BOOST_ASIO_ENABLE_CANCELIO
#endif
#endif

9
通常认为解释你的建议/答案是一个很好的礼仪。仅代码的回答可能会出奇地缺乏信息,即使它们在技术上是正确的。 - Maximilian Ast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接