DLL中声明的全局变量会发生什么变化? < P> >我在C++中写了一个DLL,并声明了一个具有非平凡析构函数的类的全局对象。卸载DLL时是否会调用析构函数?
应在应用程序结束或卸载DLL时调用析构函数,以先到者为准。请注意,这在某种程度上取决于编译时所依据的实际运行时DLL中声明的全局变量会发生什么变化? < P> >我在C++中写了一个DLL,并声明了一个具有非平凡析构函数的类的全局对象。卸载DLL时是否会调用析构函数?,c++,windows,dll,C++,Windows,Dll,应在应用程序结束或卸载DLL时调用析构函数,以先到者为准。请注意,这在某种程度上取决于编译时所依据的实际运行时 此外,还要注意非平凡的析构函数,因为它同时存在计时和排序问题。在析构函数依赖的DLL之后,您的DLL可能会被卸载,这显然会导致问题。当调用DllMain with fdreason=DLL_PROCESS_DETACH参数时,表示应用程序卸载了DLL。这是调用全局/静态对象的析构函数之前的时间。来自Microsoft的此页将详细介绍全局对象的DLL初始化和销毁: 如果要查看链接.dll
此外,还要注意非平凡的析构函数,因为它同时存在计时和排序问题。在析构函数依赖的DLL之后,您的DLL可能会被卸载,这显然会导致问题。当调用DllMain with fdreason=DLL_PROCESS_DETACH参数时,表示应用程序卸载了DLL。这是调用全局/静态对象的析构函数之前的时间。来自Microsoft的此页将详细介绍全局对象的DLL初始化和销毁:
如果要查看链接.dll时执行的实际代码,请查看
%ProgramFiles%\visualstudio 8\vc\crt\src\dllcrt0.c
从检查中,析构函数将被调用,通过代码> > CXEIT()/CUD>当DLL CRT保持的内部引用计数达到0。
< P>在Windows C++ +DLL中,所有的全局对象(包括类的静态成员)将在DLLIGRADE进程调用DLLYPROPATIONEXPLAN之前构建,它们将在调用DllMain和Dllu进程分离后立即销毁 现在,你必须考虑三个问题: 0-当然,全局非常量对象是邪恶的(但是你已经知道了,所以我将避免提及多线程、锁、上帝对象等等) 1-不保证对象或不同编译单元(即CPP文件)的构造顺序,因此如果两个对象在两个不同的CPP中实例化,则不能希望对象A在B之前构造。如果B依赖于A,这一点很重要。解决方案是在同一CPP文件中移动所有全局对象,因为在同一编译单元中,对象的实例化顺序将是构造顺序(与破坏顺序相反) 2-有些事情是禁止在校园里做的。这些东西可能也被禁止在构造器中使用。所以不要锁东西。请参阅陈雷蒙关于该主题的优秀博客:S.S:注意,C++中,构造函数可以抛出,并且不希望在DLL加载中间出现异常,因此请确保您的全局对象不会使用异常,而没有非常充分的理由。由于正确写入的析构函数无权抛出,因此在这种情况下DLL卸载应该是正常的。
在扩展名为*.exe的windows二进制图像文件中,*.DLL处于 这样的文件有入口点。您可以使用dumpbin工具查看它,如 dumpbin/headers dllname.dll 如果您使用Microsoft的C运行时,那么您的入口点如下 *CRTStartup或*DllMainCRTStartup这些函数分别执行C和C++运行时的初始化,并将委托执行分别为(main,Win)或DLLmain。 如果您使用Microsofts VC编译器,则可以在您的VC目录中查看此函数的源代码:
- crt0.c
- dllcrt0.c
- 程序启动线程的main或WinMain返回控制流
- 您明确地调用FreeLibrary并使用dll计数器为零