找出静态初始化是否结束

Finding out whether static initialization is over

本文关键字:是否 结束 初始化 静态      更新时间:2023-10-16

删节的问题(y)

假设您需要从函数内知道此函数是否被称为静态对象初始化的一部分。是否有标准或平台特定的方法?

背景故事(x)

我深处屈服于许多应用程序使用的DLL的源代码。此DLL公开了Init函数,并且该功能应构造一个boost::asio::deadline_timer以稍后使用(但是DLL可以在降级模式下使用它而无需它)。

问题是,在静态对象的初始化(dll加载时间)的初始化期间无法构造计时器,以免其构造函数僵局。

当然,每个人和他们的猫都从任何地方打电话给Init(是的,多次!),包括来自源代码的静态构造函数,我不是编辑,因此需要检测到这种情况并纾困。

实用主义克服了厌恶之后,我最终走上呼叫储备,尝试查找wWinMain并推断出静态初始化已超过。它很糟糕,并且不适用于动态装载的二进制文件,值得庆幸的是,这超出了我的特殊情况的范围。我当然希望有一种更干净的方式。

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

Init有效地无能为力。Frobnicate检查全局布尔值,以找出DLL是否确实初始化。如果没有,它首先进行了真实的初始化,这也设置了我现实化的 flag,然后实际上是在造成的。

可能,您有更多的入口点(Frobnicate2Fronbnicate3,...),因此您必须将此逻辑添加到其中的每个逻辑中。这是乏味但不是闻所未闻的。早在一天,我们曾经必须编写自己的延迟加载机制,这非常相似。当然,当时我们仅从DLL中介绍了C风格的接口,而不是带有操纵方法名称的C 样式对象,但仍然可以做到。

这假定可以延迟初始化直到第一个非Init调用到DLL。这可能是一个很好的假设。

其他骇人听闻的想法:

  • 找到一种检测装载机锁的方法(实际上是僵局除外)。如果在调用Init时持有加载程序锁,则这是"太早"时刻之一。这与您的步行到烟 - 到达 - WinMain解决方案相当。
  • 保证 Init的僵局,并使您的客户修复他们的该死的代码。
  • 创建一个仅隐藏消息的窗口,然后向其发布消息。假设客户端是一个传统的GUI应用程序,它将在同一线程上泵送消息,那么,当您收到消息时,可以安全地进行真正的初始化(希望不是太晚)。