2

假设我有一个具有以下静态/全局的 DLL:

ClassA Object;

除了 ClassA 的实现之外,它还包含一个“常规”ClassB,如果尚未构建 ClassA,它将无法正常工作(这就是为什么我将 ClassA 设为静态/全局的原因)。

在 Windows 中,我相信 DLL 加载器会在调用 ClassB 的构造函数时加载这个 DLL,对吗?至此,ClassA 将被构造,然后 ClassB 的构造将随之而来。如果出现第二个线程并构造 ClassB,则不会构造 ClassA,因为它已经构造好了。

现在,我的问题是——如果 ClassB 由两个线程同时构造会怎样。所以线程 1 将开始构造 ClassA。线程 2 会等到 ClassA 完全构造好后再执行 ClassB 的构造函数吗?

换句话说,LoadLibrary() 是否使用 CriticalSection 来确保 DLL 的静态/全局变量的线程安全初始化?我的预感是“是的”,但我似乎找不到任何文件说一种或另一种方式。

4

3 回答 3

1

查看 DllMain 的文档;我相信它谈到了加载程序锁定和初始化顺序。

于 2009-12-10T00:39:31.383 回答
1

DllMain由 Windows 加载程序调用,同时持有一个称为“加载程序锁”的内部临界区,因此您的静态构造函数将在事件期间调用,该DLL_PROCESS_ATTACH事件仅在首次加载 DLL 时发生一次。

于 2009-12-26T05:51:10.517 回答
0

DLL 不像 EXE 那样初始化,因为它们由多个进程共享。您实际上需要的是一个单例对象,它是其他对象的一次性工厂。

请注意,我在这里假设“ClassA”和“ClassB”是指这些类的实例......

例如,您可能有类似的东西

ClassA& GetTheClassAInstance();
ClassB& GetTheClassBInstsance();

第一次调用这些函数时,这些函数将确保正确构造 ClassA 和 ClassB 的全局实例。

于 2009-12-10T03:05:56.103 回答