对于DLL文件,无论隐式或是显式加载多少次,系统中只存在一个dll文件副本?
那么,如果dll中定义了一个全局的静态变量,多个调用文件都会修改此值,是否会造中变量值混乱?
如果一个执行文件中修改了dll内容,是否导致所有引用处都会修改?再请教下,运行多次exe,系统中存在多少个exe文件副本?还是无论调用多少次exe或dll,系统中只会出现一次文件中.text等不可修改section? 而全局变量等会于执行空间内另行分配内存?

解决方案 »

  1.   

    dll只是数据段和代码段而已,在一个进程内多次加载dll,只有一份。dll中的全局静态变量,要自己来做好互斥。
    运行多次exe,就有多个进程,进程是互相独立的。除非做了单实例运行,这样这个exe只能运行一个进程。要分清exe文件和 进程的概念。
      

  2.   

    假定dll中定义了一个全局变量,而这个变量会被一个导出函数AAA修改。则:
    1、当dll被多个进程加载时,每个进程都会有自己的地址空间,这个全局变量在每个进程里都各有一个,不存在混乱的问题。
    2、倒是当该dll被一个进程的多个线程加载时,如果这些线程同时调用AAA函数,则会出现混乱。因此有一种技术叫线程本地存储(TLS),LZ可以了解一下。至于“运行多次exe,系统中存在多少个exe文件副本?”的问题,我也觉得这个问题本身存在概念模糊的问题。
      

  3.   

    对于DLL文件,无论隐式或是显式加载多少次,系统中只存在一个dll文件副本?
    那么,如果dll中定义了一个全局的静态变量,多个调用文件都会修改此值,是否会造中变量值混乱?
    如果一个执行文件中修改了dll内容,是否导致所有引用处都会修改?
    ============================
    同一个DLL文件,系统中只存在一个DLL,但是数据区并不共享,共享的是代码段.对于DLL中的全局静态变量,没有实验过,但是估计也是不共享的,所以不会出现数据错乱的问题.
    如果想共享数据,应该用共享变量的方式来处理.再请教下,运行多次exe,系统中存在多少个exe文件副本?
    =============================
    同一个EXE文件两次,这两个进程之间没有任何关系.是两个独立的进程
      

  4.   

    对于同一个EXE运行多个进程,共享.code代码段吗?理论上说来,共享更好吧
      

  5.   

    问题是,32位window下,同一个EXE文件的两个进程之间并没有关系.
      

  6.   


    同意,建议找相关方向的资料看下,
    调用DLL的过程和WOW里的FB概念很类似。
      

  7.   

    1、一个exe文件,调用同一个文件夹中的dll多次,系统中只存在一个dll文件副本,dll中定义的全局静态变量也只有一个副本,会相互干扰。2、一个exe文件,调用不同文件夹中的同一个dll多次,系统中存在多个dll文件副本,dll中定义的全局静态变量也有多个副本,不会相互干扰。3、多个exe文件,调用同一个文件夹中的dll,系统中只存在一个dll文件的代码的副本,dll中定义的全局静态变量有多个副本,不会相互干扰。如果要共享数据,使用共享数据段。例如:
    #pragma data_seg(".QuitFc32WShared")
    volatile HHOOK hHook=0; // A handle to our installed hook, TRUE if hook has been installed
    volatile DWORD idThreadHook[ThreadMax]={0}; //保存QuitFc32W创建的线程句柄
    volatile int iLoad=0; //加载QuitFc32W.dll计数
    #pragma data_seg()4、多个exe文件,调用不同文件夹中的同一个dll,系统中存在多个dll文件副本,dll中定义的全局静态变量有多个副本,不会相互干扰。即便使用共享数据段也不能共享数据。5、运行多次exe,系统中存在多个exe文件副本。6、如果同一个dll的副本,改为不同名字,即便在同一个文件夹下,也视为没有任何关系的dll。
      

  8.   

    经过刚才的测试,forcal完且正确!
    另外,刚才测试同个EXE开多个进程隐试调用同一个文件夹中的dll,并修改了一个进程中DLL代码段内容,但是并没有造成其它EXE中代码更改!这似乎与只存在一个代码副本不符?
      

  9.   

    同个EXE开多个进程隐试调用同一个文件夹中的dll,系统中应只存在一个DLL,但是数据区并不共享,共享的是代码段。
    楼主所说“修改了一个进程中DLL代码段内容”,是不是修改的数据区内容,因为代码段内容似乎无法用常规方法修改。代码段通常指的是定义的那些函数。
      

  10.   

    1、不同进程有不同的地址空间,即使地址相同,也有可能被映射到不同的内存上。
    2、Copy-On-Write机制,无论是代码段还是数据区,在一般情况下,如果没有被修改,都会被映射到相同的内存上,因此加载同一个dll,内存中只有一份dll。如果有内容被修改后,会构造副本,重新映射。
      

  11.   

    读一下 programming via c++就知道了. 年轻人,多看书啊...
      

  12.   

    确实,为了测试,用的是非常规方法。不过确实是进入了DLL的加载地址进行修改了!
    原来如此!
    这样就造成了多个DLL副本共存了!