首页 / 知识
关于c ++:在DLL中声明的全局变量会怎样?
2023-04-16 03:16:00

What happens to global variables declared in a DLL?假设我用C ++编写了一个DLL,并使用非平凡的析构函数声明了一个类的全局对象。 卸载DLL时将调用析构函数吗? 在Windows C ++ DLL中,所有全局对象(包括类的静态成员)都将在使用DLL_PROCESS_ATTACH调用DllMain之前构造,并且在使用DLL_PROCESS_DETACH调用DllMain之后立即销毁它们。 现在,您必须考虑三个问题: 0-当然,全局非常量对象是邪恶的(但是您已经知道了,所以我将避免提及多线程,锁,上帝对象等)。 1-不保证对象或不同编译单元(即CPP文件)的构造顺序,因此,如果在两个不同的CPP中实例化两个对象,您就不能希望在B之前构造对象A。如果B依赖于A,这一点很重要。解决方案是将所有全局对象移动到同一CPP文件中,就像在同一编译单元内部一样,对象的实例化顺序将是构造顺序(以及该顺序的相反顺序)。破坏) 2-DllMain中禁止执行某些操作。这些东西也可能在构造函数中被禁止。因此,避免锁定某些东西。请参阅Raymond Chen关于该主题的出色博客: http://blogs.msdn.com/oldnewthing/archive/2004/01/27/63401.aspx http://blogs.msdn.com/oldnewthing/archive/2004/01/28/63880.aspx 在这种情况下,惰性初始化可能会很有趣:类保持在"未初始化"状态(内部指针为NULL,布尔值为false,无论如何),直到您调用它们的方法之一为止,此时它们将自行初始化。如果在主体(或主体的后代函数之一)中使用这些对象,则可以,因为在执行DllMain之后将调用它们。 3-当然,如果DLL A中的某些全局对象依赖于DLL B中的全局对象,则您应非常小心DLL的加载顺序,并因此确保依赖关系。在这种情况下,具有直接或间接循环依赖关系的DLL将使您发疯。最好的解决方案是打破循环依赖。 附注:请注意,在C ++中,构造函数会抛出异常,并且您不希望在DLL加载过程中发生异常,因此请确保您的全局对象在没有非常充分的理由的情况下不会使用异常。由于正确编写的析构函数无权抛出,因此在这种情况下DLL卸载应该可以。
Microsoft的本页详细介绍了DLL初始化和全局变量销毁的细节:
如果要查看链接.dll时执行的实际代码,请查看
从检查来看,当由dll CRT维护的内部引用计数达到零时,将通过 当应用程序结束或DLL卸载时(以先到者为准),应调用它。请注意,这在某种程度上取决于要编译的实际运行时。 另外,请注意非平凡的析构函数,因为同时存在时序和排序问题。在您的析构函数所依赖的DLL之后,您的DLL可能会被卸载,这显然会引起问题。
在扩展名为* .exe的Windows二进制图像文件中,*。dll为PE格式
如果您使用Microsoft的C运行时,则您的入口点将类似于 这些函数执行c和c ++运行时的初始化,并将执行分别委派给(main,WinMain)或DllMain。 如果使用Microsoft的VC编译器,则可以在VC目录中查看此函数的源代码:
在正常情况下,DllMainCRTStartup过程处理所有事情都需要从.data节中初始化/取消初始化全局变量,当它在dll卸载期间检索通知DLL_PROCESS_DETACH时。例如:
当调用带有fdwReason = DLL_PROCESS_DETACH参数的DllMain时,这意味着该DLL已由应用程序卸载。这是调用全局/静态对象的析构函数之前的时间。 |
最新内容
相关内容
python声明变量
python声明变量,培训,代码,变量,赋值,字符串,类型,语句,函数,上面,声明,首先,在Python解释器中输入如下内容:>>>a=5上面代码没有生成任何输出,只python声明变量类型
python声明变量类型,培训,代码,基础,变量,赋值,类型,字符串,语句,函数,上面,对于没有编程基础的读者,可以先不编写真正的Python程序,而是先打开python变量不需要声明吗
python变量不需要声明吗,培训,数字,变量,代码,合法,声明,类型,整数,字符串,布尔,Python中常见的数据类型有字符串,整形,列表,元组,字典等。在Pythpython怎么声明变量
python怎么声明变量,培训,通用,一致,数字,变量,声明,字符串,引号,方式,类型,python声明变量:1、变量声明声明变量的时候,直接使用例如a=1这样的python变量使用前需声明嘛
python变量使用前需声明嘛,培训,代码,基础,变量,赋值,字符串,类型,语句,函数,上面,Python使用等号(=)作为赋值运算符,例如a=20就是一条赋值语python构造函数和析构函数是一样的
python构造函数和析构函数是一样的吗,系统,培训,函数,状态,对象,方法,契机,时候,实例,初始化,python构造函数和析构函数:1、构造方法的使用很python需要声明类型吗
python需要声明类型吗,数据,培训,中心,类型,声明,语言,变量,内存空间,内存,整数,在其他语言中,例如C/C++语言中在存储一个数据之前,都需要在内python如何声明函数
python如何声明函数,培训,函数,较大,合法,代码,画线,工具,定义,单词,参数,python函数的定义定义函数,也就是创建一个函数,可以理解为创建一个具python定义变量需要声明类型吗
python定义变量需要声明类型吗,培训,数字,变量,合法,代码,声明,类型,整数,布尔,字符串,在Python语言中,声明变量的同时需要为其赋值,毕竟不代表pythonpython的声明变量类型
pythonpython的声明变量类型,培训,数字,变量,名字,代码,概念,合法,声明,类型,整数,变量(variable)是Python语言中一个非常重要的概念。变量的python需要声明类型吗
python需要声明类型吗,数据,培训,代码,中心,类型,声明,语言,变量,内存空间,内存,python不用去声明变量的类型,是由于其“若类型”的语言特性决python模块中判断全局变量的赋值
python模块中判断全局变量的赋值,培训,模块,赋值,脚本,属性,所在,以上,原因,方法,教程,python模块中判断全局变量的赋值1、在模块中,我们需要