Windows LoadLibrary静态/全局和线程

Windows LoadLibrary静态/全局和线程,windows,dll,thread-safety,loadlibrary,Windows,Dll,Thread Safety,Loadlibrary,假设我有一个DLL,它具有以下静态/全局: ClassA Object; 除了ClassA的实现之外,它还包含一个“常规”ClassB,如果尚未构建ClassA,它将无法正常工作(这就是为什么我将ClassA设置为静态/全局) 在Windows中,我相信DLL加载程序会在调用ClassB的构造函数时加载这个DLL,对吗?此时,将构造ClassA,然后再构造ClassB。如果出现第二个线程并构造ClassB,则不会像已经构造的那样构造ClassA 现在,我的问题是——如果ClassB是由两个线程

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

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

在Windows中,我相信DLL加载程序会在调用ClassB的构造函数时加载这个DLL,对吗?此时,将构造ClassA,然后再构造ClassB。如果出现第二个线程并构造ClassB,则不会像已经构造的那样构造ClassA

现在,我的问题是——如果ClassB是由两个线程同时构造的呢。因此线程1将开始构造ClassA。线程2会在执行ClassB的构造函数之前等待ClassA被完全构造吗


换句话说,LoadLibrary()是否使用CriticalSection来确保DLL静态/全局的线程安全初始化?我的直觉是“是的”,但我似乎找不到任何说明这种或那种方式的文档。

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

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

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

例如,你可以有一个类似

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

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

DllMain
由Windows加载程序在持有称为“加载程序锁”的内部关键部分时调用,因此您的静态构造函数将在
DLL\u PROCESS\u ATTACH
事件期间调用,该事件只发生一次,当您的DLL第一次加载时。

谢谢——这与我对DllMain文档的解释相一致,但我发现其他人也同意我的解释,这让我松了一口气。