当调⽤的DLL中有全局变量时调⽤它的多个实例是否共享同⼀
个全局变量
当调⽤的DLL中有全局变量时调⽤它的多个实例是否共享同⼀个全局变量
问题的起因原于⾃⼰在⼯作中需要调⽤⼀个动态库,⽽其中要⽤到⼀个全局的变量才能把需要的句柄给传出来,于是就想,如果有多个进程要调⽤这个动态库时,后⾯的进程调⽤同⼀个动态库时,是否会把以前调⽤同⼀个动态库时的全局变量的值改变
我猜想应该是不会的吧,于是带着这个疑惑,我写了⼀个⽰例程序来验证⾃⼰的想法。⽰例代码如下:
Step1
⾸先创建⼀个动态库⼯程globalTest,这个动态库中要有⼀个全局变量,为了更加明显的证明,我在这个动态库中定义了两个函数来操纵这个全局变量:
(1).def⽂件的代码如下:
LIBRARY globalTest
EXPORTS
testGlobal
showGlobal
(2).h⽂件的代码如下:
int testGlobal(int *global);
int showGlobal(int *global);
(3).cpp⽂件的代码如下:
// globalTest.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
int dllGlobal = 0;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
int testGlobal(int *global)
{一个线程可以包含多个进程
dllGlobal += 5;
*global = dllGlobal;
return 0;
}
int showGlobal(int *global)
{
*global = dllGlobal;
return 0;
}
然后编译⽣成DLL和LIB⽂件,供以下调⽤程序调⽤。Step2
创建⼀个控制台程序callglobalTest,来调⽤上述DLL (1).h⽂件的代码如下:
int testGlobal(int *global);
int showGlobal(int *global);
(2).cpp⽂件的代码如下:
#include <windows.h>
#include <stdio.h>
#include "callglobalTest.h"
int main()
{
int test = 1;
for(int i = 0; i < 4; i++)
{
testGlobal(&test);
printf("test = %d /n",test);
Sleep(3000);
}
showGlobal(&test);
printf("test = %d /n",test);
Sleep(5000);
printf("Sleep 5000 End");
Sleep(5000);
return 0;
}
然后将上述DLL和LIB⽂件拷贝到本⼯程⽬录下边,在此⼯程中添加上LIB⽂件,然后编译运⾏。
Step3
为了验证⾃⼰的猜测,要同时运⾏上述调⽤程序callglobalTest,同时运⾏结果如下:
<!--[if !vml]--><!--[endif]-->
可以看到同时运⾏时,第⼆次调⽤DLL并没有改变全局变量的值
附录说明:
上述所说的问题其实就是:DLL与进程的地址空间问题。
⼀旦D L L的⽂件映像被映射到调⽤进程的地址空间中, D L L的函数就可以供进程中运⾏的所有线程使⽤。实际上, D L L⼏乎将失去它作为D L L的全部特征。对于进程中的线程来说,D L L的代码和数据看上去就像恰巧是在进程的地址空间中的额外代码和数据⼀样。当⼀个线程调⽤D L L函数时,该D L L函数要查看线程的堆栈,以便检索它传递的参数,并将线程的堆栈⽤于它需要的任何局部变量。此外, D L L中函数的代码创建的任何对象均由调⽤线程所拥有,⽽D L L本⾝从来不拥有任何东西。
例如,如果Vi r t u a l A l l o c函数被D L L中的⼀个函数调⽤,那么将从调⽤线程的进程地址空间中保留⼀个地址空间的区域,该地址空间区域将始终处于保留状态,因为系统并不跟踪D L L中的函数保留该区域的情况。保留区域由进程所拥有,只有在线程调⽤Vi r t u a l F r e e函数或者进程终⽌运⾏时才被释放。
如你所知,可执⾏⽂件的全局变量和静态变量不能被同⼀个可执⾏⽂件的多个运⾏实例共享。Windows 98能够确保这⼀点,⽅法是在可执⾏⽂件被映射到进程的地址空间时为可执⾏⽂件的全局变量和静态变量分配相应的存储器。Windows 2000确保这⼀点的⽅法是使⽤第1
3章介绍的写⼊时拷贝(c o p y - o n - w r i t e)机制。D L L中的全局变量和静态变量的处理⽅法是完全相同的。当⼀个进程将D L L的映像⽂件映射到它的地址空间中去时,系统将同时创建全局数据变量和静态数据变量的实例。
^-^呵呵,写到这⾥吧,⼿都累了,希望对⼤家有所帮助。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论