静态成员破坏

时间:2012-09-19 13:45:18

标签: c++ windows dll static

我不是静态的粉丝,但我有一些代码:

除非出现其他问题,否则静态破坏将失败。 static被声明为DLL类中的成员。

可执行文件正在关闭,因此运行时调用FreeLibary来释放它在启动时加载的DLL。

我知道静止将在我的程序终止期间被销毁(由于无法保证施工顺序,因此无法保证销毁订单)但是什么时候才能进行销毁?在我的DLLMain(对于加载的DLL)退出之后或在运行时__DllMainCRTStartup之后,甚至在此之后?

我只是想知道在破坏之前是否有机会做某事,如果不是,我需要考虑将静态去除更合适的东西。

3 个答案:

答案 0 :(得分:1)

根据您的问题,我了解您使用的是Windows,以及Microsoft编译器。我的回答是针对这个设置的(虽然我很确定gcc是相似的)。

简短的回答是:
只要你的DLL存在,并且它依赖于另一个DLL,并且你不搞砸事情(例如你没有FreeLibrary的依赖),那么依赖DLL在工作状态下仍然在内存中,并且可以叫做。 只有在DLL完全关闭后,依赖DLL上的关闭序列才会启动。

使用Microsoft Visual Studio编译的DLL的序列顺序:

  • DllMainCRTStartup是DLL的入口点。您可以在以下位置查看此方法的代码: c:\ program files \ Microsoft Visual Studio 11.0 \ VC \ CRT \ src \ crtdll.c
  • DllMainCRTStartup调用CRT_INIT(同一文件)。
  • 在DLL_PROCESS_ATTACH中有各种初始化。然后调用函数 initterm 。这个函数(在别处实现,见下文)是调用所有静态C ++对象的构造函数的函数。
  • 在DLL_PROCESS_DETACH中,CRT_INIT调用一堆执行销毁的onexit / atexit例程。
  • 调用CRT_INIT后,DllMainCRTStartup调用用户定义的DllMain。
  • terminit在crt0dat.c中实现。它有一个指向函数的指针数组(由编译器和链接器生成),这些指针在循环中调用。每个函数都是静态对象的构造函数。

答案 1 :(得分:1)

也许 atexit 功能会对您有所帮助。你给它一个回调函数,它将在进程分离期间由运行时执行。

DLL说明:http://msdn.microsoft.com/en-us/library/988ye33t.aspx

atexit:http://msdn.microsoft.com/en-us/library/tze57ck3.aspx

答案 2 :(得分:0)

我认为另一种可能的方法是建立一个全局类,其构造函数只调用CoInitilize和析构函数调用CoUninitilize

然后确保在包含ComPtr的对象之前创建此全局。由于破坏将与构造相反,因此调用CoUninitilize的析构函数将在.Release上调用ComPtr后发生。