在共享库中初始化全局数据的最佳方法是什么?

sra*_*mij 3 c++ dll global-variables shared-libraries

我有一个单独的类来完成所有必需的初始化.目前我已经声明了这个类类型的全局对象,它正在库加载上实例化.我已经看到了其他方式,比如贬义

BOOL APIENTRY DllMain
Run Code Online (Sandbox Code Playgroud)

共享库的入口点,并在进程附加上进行实际初始化.

这与让隐式全局初始化到它的工作有什么不同?哪种方式更好?

ham*_*ene 6

这是在C++ DLL启动期间发生的事情:

  1. 系统调用DLL的入口点,由编译器生成
  2. 入口点调用DllMainCRTStartup(名称可能不同),它初始化C/C++运行时并实例化所有全局对象.
  3. 然后DllMainCRTStartup调用用户定义的DllMain.

我个人更喜欢DllMain,因为这样我可以明确地控制初始化的顺序.当您在不同的编译单元中使用全局对象时,它们将以随机顺序初始化,这可能会在截止日期前10分钟带来一些意外的惊喜.

DllMain还允许你进行每线程初始化,这是使用全局对象无法实现的.但是,它无法移植到其他平台.

PS你不需要在DllMain中使用互斥锁,因为对它的所有调用都已经在进程全局关键部分进行了序列化.即保证两个线程不会出于任何目的同时进入它.这也是你不应该与其他线程通信,从这个函数加载其他库等的原因; 有关解释,请参阅MSDN文章.