【问题标题】:Boost::asio winsock and winsock 2 compatibility issueBoost::asio winsock 和 winsock 2 兼容性问题
【发布时间】: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 已经包含

【问题讨论】:

    标签: c++ boost-asio winsock c-preprocessor winsock2


    【解决方案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 &lt;SDKDDKVer.h&gt; 是最终帮助我克服这一切的缺失的想法。谢谢!
    【解决方案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 之上并解决问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多