【问题标题】:undefined reference to `std::errc::operation_canceled` when compiling websocketpp example code with mingw使用 mingw 编译 websocketpp 示例代码时对“std::errc::operation_canceled”的未定义引用
【发布时间】:2015-11-12 01:08:59
【问题描述】:

我正在尝试使用websocketpp 编写一个使用websockets 进行通信的跨平台程序。我想使用基于asio 的传输层。

我的理解是,如果我使用 C++11,我可以将 asio 配置为独立于 boost 并使用 std::thread,并且 websocketpp 在这种情况下同样是仅标头。

但是,当我实际尝试以这种方式编译任何 websocketpp 教程时,例如 tutorials/utility_client,它在 g++ 和 clang 上运行良好,但在 mingw 上出现奇怪的编译错误:

In file included from websocketpp-0.6.0/include/websocketpp/config/asio_no_tls_client.hpp:32:0,
                 from main.cpp:7:
websocketpp-0.6.0/include/websocketpp/transport/asio/endpoint.hpp: In member function ‘void websocketpp::transport::asio::endpoint<config>::handle_accept(websocketpp::transport::accept_handler, const error_code&)’:
websocketpp-0.6.0/include/websocketpp/transport/asio/endpoint.hpp:764:28: error: ‘operation_canceled’ is not a member of ‘std::errc’
             if (asio_ec == lib::asio::errc::operation_canceled) {
                            ^

我对这意味着什么以及如何解决这个问题摸不着头脑。这似乎与缺少 boost 无关——std::errc::operation_canceled 似乎是根据this, not always accurate, website 定义良好的 C++11 符号。这是否意味着我的工具链损坏/有缺陷?我尝试安装不同版本的 mingw 工具链,但遇到了同样的问题。

我找不到任何对没有找到此符号有类似问题的任何人的引用,所以也许我配置库错误?这是我的编译行:

"$CXX" -std=c++11 -Iasio-1.10.6/include -Iwebsocketpp-0.6.0/include -D_WEBSOCKETPP_CPP11_THREAD_=1 -DASIO_STANDALONE=1 main.cpp -lpthread

I made a repository 以帮助重现我的确切设置,但这里没有太多内容——我从各自的 repos 中下载了最新版本的两个库。由于编译在 main.cpp 的包含体之一中死掉了,似乎并不是很相关,但我只是在使用他们的教程代码。

如果有人能就此问题给我留言,我将不胜感激。 :)

编辑:我不太确定,但我已将其报告为 mingw-w64 的错误: http://sourceforge.net/p/mingw-w64/support-requests/105/

【问题讨论】:

    标签: c++ c++11 websocket boost-asio mingw-w64


    【解决方案1】:

    我已将其报告为 mingw-w64 的错误

    mingw-w64 编译器不符合 C++11 标准,未定义此错误代码, 但人们已经知道了,这是故意的。 (虽然我不 知道为什么他们无法修复它。)

    相关头文件为:

    <toochain_dir>/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/error_constants.h
    

    这里是enum class std::errc的定义:

    // Most of the commented-out error codes are socket-related and could be
    // replaced by Winsock WSA-prefixed equivalents.
      enum class errc
        {
    //    address_family_not_supported =        EAFNOSUPPORT,
    //    address_in_use =              EADDRINUSE,
    //    address_not_available =           EADDRNOTAVAIL,
    //    already_connected =           EISCONN,
          argument_list_too_long =          E2BIG,
          argument_out_of_domain =          EDOM,
          bad_address =                 EFAULT,
          bad_file_descriptor =             EBADF,
    //    bad_message =                 EBADMSG,
          broken_pipe =                 EPIPE,
    //    connection_aborted =          ECONNABORTED,
    //    connection_already_in_progress =      EALREADY,
    //    connection_refused =          ECONNREFUSED,
    //    connection_reset =            ECONNRESET,
    //    cross_device_link =           EXDEV,
    //    destination_address_required =        EDESTADDRREQ,
          device_or_resource_busy =         EBUSY,
          directory_not_empty =             ENOTEMPTY,
          executable_format_error =         ENOEXEC,
          file_exists =                     EEXIST,
          file_too_large =              EFBIG,
          filename_too_long =           ENAMETOOLONG,
          function_not_supported =          ENOSYS,
    //    host_unreachable =            EHOSTUNREACH,
    //    identifier_removed =          EIDRM,
          illegal_byte_sequence =           EILSEQ,
          inappropriate_io_control_operation =  ENOTTY,
          interrupted =                 EINTR,
          invalid_argument =            EINVAL,
          invalid_seek =                ESPIPE,
          io_error =                EIO,
          is_a_directory =              EISDIR,
    //    message_size =                EMSGSIZE,
    //    network_down =                ENETDOWN,
    //    network_reset =               ENETRESET,
    //    network_unreachable =             ENETUNREACH,
    //    no_buffer_space =             ENOBUFS,
    #ifdef _GLIBCXX_HAVE_ECHILD
          no_child_process =            ECHILD,
    #endif
    //    no_link =                 ENOLINK,
          no_lock_available =           ENOLCK,
    //    no_message_available =            ENODATA,
    //    no_message =              ENOMSG,
    //    no_protocol_option =          ENOPROTOOPT,
    #ifdef _GLIBCXX_HAVE_ENOSPC
          no_space_on_device =          ENOSPC,
    #endif
    //    no_stream_resources =             ENOSR,
          no_such_device_or_address =       ENXIO,
          no_such_device =              ENODEV,
          no_such_file_or_directory =       ENOENT,
          no_such_process =             ESRCH,
          not_a_directory =             ENOTDIR,
    //    not_a_socket =                ENOTSOCK,
    //    not_a_stream =                ENOSTR,
    //    not_connected =               ENOTCONN,
          not_enough_memory =           ENOMEM,
    #ifdef _GLIBCXX_HAVE_ENOTSUP
          not_supported =               ENOTSUP,
    #endif
    //    operation_canceled =          ECANCELED,
    //    operation_in_progress =           EINPROGRESS,
    #ifdef _GLIBCXX_HAVE_EPERM
          operation_not_permitted =         EPERM,
    #endif
    //    operation_not_supported =         EOPNOTSUPP,
    #ifdef _GLIBCXX_HAVE_EWOULDBLOCK
          operation_would_block =           EWOULDBLOCK,
    #endif
    //    owner_dead =              EOWNERDEAD,
          permission_denied =           EACCES,
    //    protocol_error =              EPROTO,
    //    protocol_not_supported =          EPROTONOSUPPORT,
          read_only_file_system =           EROFS,
          resource_deadlock_would_occur =       EDEADLK,
          resource_unavailable_try_again =      EAGAIN,
          result_out_of_range =             ERANGE,
    //    state_not_recoverable =           ENOTRECOVERABLE,
    //    stream_timeout =              ETIME,
    //    text_file_busy =              ETXTBSY,
    #ifdef _GLIBCXX_HAVE_ETIMEDOUT
          timed_out =               ETIMEDOUT,
    #endif
          too_many_files_open_in_system =       ENFILE,
          too_many_files_open =             EMFILE,
          too_many_links =              EMLINK
    //    too_many_symbolic_link_levels =       ELOOP,
    #ifdef _GLIBCXX_HAVE_EOVERFLOW
        ,
          value_too_large =             EOVERFLOW
    #endif
    //    wrong_protocol_type =             EPROTOTYPE
       };
    

    您会看到operation_canceled 是其中之一。

    按照那里的建议,您需要使用 winsock 错误代码WSAECANCELLED, 在winerror.h 中定义。如果你想要便携性,当然你需要 以主机操作系统的编译时确定为条件,而不是std::errc::operation_canceled 使用此功能。

    【讨论】:

    • 谢谢你,我认为你是对的。我决定尝试在我的项目中以不同的方式对其进行修补,而不是尝试引入新的枚举值,或者使其依赖于平台定义。相反,我尝试使用 SFINAE 来检测是否缺少所需的枚举值。我在此处对 websocketpp 进行了 PR:github.com/zaphoyd/websocketpp/pull/479/files
    猜你喜欢
    • 2012-05-30
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多