【发布时间】:2020-03-28 16:04:01
【问题描述】:
假设我构建了一个简单的 DLL,由两个翻译单元组成:
第一
// foo.cpp
struct Foo
{
//...
} g_foo;
// ... other stuff
第二个
// bar.cpp
struct Bar
{
//...
} g_bar;
// ... other stuff
我知道 C++ 标准没有指定全局变量初始化的顺序。问题是:一旦我构建了 Windows DLL,在LoadLibrary 调用期间执行的全局变量初始化的顺序是确定性的(每个LoadLibrary 调用都会以相同的顺序启动变量g_foo 和g_bar 的初始化)或者它可能取决于一些加载器/系统设置?
【问题讨论】:
-
如DllMain 的文档和链接的一般最佳实践中所述,您可以在其中执行的操作:只有
Kernel32.dll可以假定为已加载,在DllMain内部。因此:库的实际加载顺序是不确定的。 -
无论使用多少个翻译单元来创建它,一个 DLL 只能有一个 DllMain 函数,这就是 Windows 为初始化 DLL 而调用的函数。从那时起,DLL 中初始化选项的顺序由 DLL 本身的代码决定。所以是的,如果你的 DLL 没有改变,初始化的顺序应该是一致的。但我当然同意你需要非常小心你在 DllMain 时所做的事情,其中包括静态变量初始化器。
-
@AlgirdasPreidžius 我的意思是同一个库中全局变量的初始化顺序。将此添加到问题描述中。
-
@undermind 我不知道这是否能解决您的直接问题,但我记得前一段时间搜索过,关于何时在 DLL 中初始化全局对象:devblogs.microsoft.com/oldnewthing/20141017-00/?p=43823;这更通用,当全局变量被初始化时,关于 C++ 标准:stackoverflow.com/questions/54159044/…(有多个类似的问题)。
标签: c++ visual-c++ dll global-variables initialization-order