使用 mingw 编译 websocketpp 示例代码时对 std::errc::operation_canceled 的未定义引用
undefined reference to `std::errc::operation_canceled` when compiling websocketpp example code with mingw
我正在尝试使用 websocketpp
编写一个 cross-platform 程序,该程序使用 websockets 进行通信。我想使用基于 asio
的传输层。
我的理解是,如果我使用的是 C++11,我可以从 boost 配置 asio
到 stand-alone 并使用 std::thread
,而 websocketpp
是同样header-only在这种情况下。
然而,当我实际尝试以这种方式编译任何 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) {
^
我绞尽脑汁想知道这是什么意思以及如何解决这个问题。这似乎与缺少提升无关——根据 this, not always accurate, website,std::errc::operation_canceled
似乎是一个 well-defined 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 以帮助重现我的确切设置,但这里没有太多进展——我从各自的回购协议中下载了最新版本的两个库。由于编译死于其中一个包含 main.cpp
的 body 似乎不太相关,但我只是在使用他们的教程代码。
如果有人能就此给我留言,我将不胜感激。 :)
编辑:我不太确定,但我已将此报告为 mingw-w64 上的错误:
http://sourceforge.net/p/mingw-w64/support-requests/105/
I have reported this as a bug at 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
以主机 OS 的编译时确定为条件。
我正在尝试使用 websocketpp
编写一个 cross-platform 程序,该程序使用 websockets 进行通信。我想使用基于 asio
的传输层。
我的理解是,如果我使用的是 C++11,我可以从 boost 配置 asio
到 stand-alone 并使用 std::thread
,而 websocketpp
是同样header-only在这种情况下。
然而,当我实际尝试以这种方式编译任何 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) {
^
我绞尽脑汁想知道这是什么意思以及如何解决这个问题。这似乎与缺少提升无关——根据 this, not always accurate, website,std::errc::operation_canceled
似乎是一个 well-defined 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 以帮助重现我的确切设置,但这里没有太多进展——我从各自的回购协议中下载了最新版本的两个库。由于编译死于其中一个包含 main.cpp
的 body 似乎不太相关,但我只是在使用他们的教程代码。
如果有人能就此给我留言,我将不胜感激。 :)
编辑:我不太确定,但我已将此报告为 mingw-w64 上的错误: http://sourceforge.net/p/mingw-w64/support-requests/105/
I have reported this as a bug at 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
以主机 OS 的编译时确定为条件。