找出静态初始化是否结束

时间:2017-11-22 16:35:29

标签: c++ static-initialization

删节问题(Y)

假设您需要从函数中知道是否已将此函数作为静态对象初始化的一部分进行调用。是否有标准或特定于平台的方法?

背景故事(X)

我深入研究了许多应用程序使用的DLL的源代码。这个DLL暴露了一个Init函数,这个函数应该构造一个稍后要使用的boost::asio::deadline_timer(但是DLL可以在没有降级模式的情况下工作)。

问题是在静态对象初始化期间(DLL加载时间)lest its constructor deadlock无法构造计时器。

当然,每个人和他们的猫从任何地方(是的,多次!)调用Init,包括我编辑的源代码中的静态构造函数,因此需要检测这种情况并拯救

实用主义克服了厌恶之后,我最终走上callstack尝试找到wWinMain并推断出静态初始化已经结束了。它非常糟糕,并且不适用于动态加载的二进制文件,值得庆幸的是,这超出了我特定情况的范围。我当然希望有一种更清洁的方式。

1 个答案:

答案 0 :(得分:1)

目前,我们假设您的DLL有两个入口点:InitFrobnicate

Init实际上什么也没做。 Frobnicate检查全局布尔值,以确定DLL是否曾真正初始化。如果没有,它首先进行真正的初始化,在实际进行frobnicating之前,它还设置我已经初始化的标志。

可能,您有更多的入口点(Frobnicate2Fronbnicate3,...),因此您必须将此逻辑添加到其中的每一个中。这很乏味但不是闻所未闻。在当天,我们过去必须编写自己的延迟加载机制,这非常相似。当然,我们当时只提供了来自DLL的C风格接口,而不是带有错位方法名称的C ++风格对象,但它仍然必须可行。

这假设在第一次非Init调用DLL之前,可以延迟初始化。这可能是也可能不是一个好假设。

其他愚蠢的想法:

  • 找到一种检测加载程序锁定的方法(除了实际的死锁)。如果在调用Init时保持加载程序锁定,则这是“太快”时刻之一。这与您的步入式堆栈 - WinMain解决方案相同。
  • 当过早调用Init时,做一些保证死锁的事情,让你的客户修复他们该死的代码。
  • 创建一个隐藏的仅限消息的窗口并向其发送消息。假设客户端是一个传统的GUI应用程序,它将在同一个线程上传送消息,那么,当您收到消息时,进行真正的初始化(并且希望不会太晚)应该是安全的。