【问题标题】:How to control boost::asio initialisation on Windows?如何在 Windows 上控制 boost::asio 初始化?
【发布时间】:2013-11-11 16:19:01
【问题描述】:

我正在为运行 Windows 7 Embedded 的系统开发程序。 该程序使用boost::asio 套接字在 UDP 和 TCP 套接字上进行通信(它充当 DHCP 服务器,由 RESTful 接口控制)。

通常它工作正常。但是,有时它不会正确初始化并且不会响应任何 DHCP 或 HTTP 消息。我怀疑这是因为程序在底层Winsock 准备好之前就已经启动了。在使用以下代码创建 boost::asio::io_service 和套接字之前,我天真地试图等待 Winsock 初始化:

WSADATA wsaData;
while (WSAStartup(MAKEWORD(2,2), &wsaData))
{
  BOOST_LOG_TRIVIAL(error) << "WSAStartup failed, waiting...";
  boost::this_thread::sleep_for(COMMS_DELAY_PERIOD);
}

但我现在意识到boost::asio 在Windows 系统上调用main 之前初始化。见winsock_init.hpp下面的代码:

// Static variable to ensure that winsock is initialised before main, and
// therefore before any other threads can get started.
static const winsock_init<>& winsock_init_instance = winsock_init<>(false);

有没有办法确保asio在使用前在Windows系统中正确初始化,而不用编辑DLL?

【问题讨论】:

  • 谢谢@StefanNäwe。然而,winsock_init.hpp 的 1.54 版本中的一条评论指出:“使用 MSVC,这可以通过将以下代码添加到 DLL 来实现...”你知道如何做到这一点无需编辑动态链接库?
  • 你是开发者,不能改变你的 DLL ?
  • 哈哈@Stefan 很有趣。我无法编辑 my DLL,因为我没有!但是,在仔细检查 winsock_init.hpp 中的 cmets 后,我意识到我可以禁用它,如下所示。

标签: boost-asio winsock winsock2


【解决方案1】:

现在意识到 winsock_init.hpp 中关于 DLL 的 cmets 只是一个示例,asio 库并未内置到 DLL 中。 此外,示例代码仅适用于 MSVC(并不奇怪,因为它是特定于 Windows 的)。然而,在我们的项目中,我们在 Qt 下使用 MSVC 和 MinGw (gcc) 构建。以下代码对我们有用:

#include <boost/asio/detail/winsock_init.hpp>
#ifdef _MSC_VER
  #pragma warning(push)
  #pragma warning(disable:4073)
  #pragma init_seg(lib)
  boost::asio::detail::winsock_init<>::manual manual_winsock_init;
  #pragma warning(pop)
#else // using MinGw (gcc)
  boost::asio::detail::winsock_init<>::manual manual_winsock_init
    __attribute__ ((init_priority (101)));
#endif

【讨论】:

  • 如果您能分享的不仅仅是来自 boost 头文件的复制和粘贴,那就太好了。所有这些都是增加 winsock_init 对象的静态 data_ 成员中的 ref 计数器,从而绕过内部 WSAStartup。这本身并不是一个解决方案。
猜你喜欢
  • 1970-01-01
  • 2020-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-21
相关资源
最近更新 更多