如果一个DLL文件被多个Exe时,则该dll只被加载了一次,还是分别被加载?

解决方案 »

  1.   

    理论上,windows OS在Physical Memory加载一个dll,当一个exe使用一个dll时,该exe进程会将dll “map”到自己的virtual address space里,当然当另一个exe调用此dll时,同样也会将dll“map”到自己的virtual address space,(当然如果要在dll做一些memory sharing也可以,很简单,但那时另一个话题)当无人再使用一个dll时(reference count = 0),Windows会将dll从physical memory里remove掉。
      

  2.   

    Yes. 其实这就是为什么需要动态链接库的原因。
      

  3.   

    正好这个问题也是我关心的
    我在一个Exe程序里,对同一个Dll我想同时加载多个,并且这多个加载的对象之间的数据互不影响,能做到吗?
    多谢
      

  4.   

    如果该dll没被加载过,则加载,如果加载过,则将dll的内存映射入该exe的进程空间,如果dll中的数据区没有被共享,则每一进程有这些数据的一分拷贝。
      

  5.   

    DLL的数据段有Copy-On-Write(写入时复制)的属性,不同进程间对同一DLL的数据写入互相不会影响
      

  6.   

    就是定义了一些Struct,然后用CArray《Struct》保存了一些信息,然后在这个DLl的导出行数里对会对这些信息进行操作,由于这些信息的管理是放在别的类中实现的,因此在导出函数中用theApp.CDataManager.调用的方式对信息进行操作;
      

  7.   

    对啊,按道理来说,应该是不会影响才是,但是结果确实是影响了。。
    因为接触Dll不深,所以不明白问题在哪,请教各位帮忙
    我跟了一下,两次LoadLibrary得到的HINSTANCE地址是一样的,这个是正常的吗?
      

  8.   

    HINSTANCE 的值其实就是该DLL在进程内存中的基地址
    HINSTANCE相同是十分正常的事
      

  9.   

    HINSTANCE 的值其实就是该DLL在进程内存中的基地址???HINSTANCE 只是与DLL的起始内存地址有关联,并不是直接的地址。
      

  10.   

    to:wenxy1(周末了,极速飙车)你用把 HINSTANCE 的值打印出来就回明白的
      

  11.   

    HINSTANCE 与加载无关,它是每个进程加截段的起始地址
    两次相同,表明你加载逻辑位置相同
    如下就不会相同了:
    A进程:
    LoadLibrary("Adll.dll");B进程:
    LoadLibrary("Bdll.dll");
    LoadLibrary("Adll.dll");注:在DLLMAIN入口的参数是共享的,用于加载,引用,释放,消毁,一般不要改动
    其它就是共享段,楼上都讲了
      

  12.   

    hInstance Differences Under Win 3.1 and Win32 PlatformsPSS ID Number: Q103644Article Last Modified on 07-12-2000
    --------------------------------------------------------------------------------
    The information in this article applies to: Microsoft Win32 Software Development Kit (SDK)--------------------------------------------------------------------------------
    Summary
    In 16-bit Windows (Win16) applications running on Windows 3.1, an instance handle can be used to uniquely identify the instance of an application because instance handles are unique within the scope of an address space. Because each instance of a 32-bit Windows (Win32) application runs in its own address space, instance handles cannot be used to uniquely identify an instance of an application running on the system. This article explains why, and includes some alternative calls that might assist in uniquely identifying an Win32 application instance. More Information
    Although the concepts for an instance handle are similar between Win32 and Win16, the results you see regarding them might be very different from what you expect. With Win16, when you start several instances of the same application, they all share the same address space. You have multiple instances of the same code segment. However, each of these instances has a unique data segment associated with it. Using an instance handle (hInstance) is a way to uniquely identify these different instances and data segments in the address space. Instance handles are unique to the address space. On Windows NT, when looking at the value of the instance handle, or the value returned from GetWindowLong(hWnd, GWL_HINSTANCE), a developer coming from a Win16 background might be surprised to see that most of the windows on the desktop return the same value. This is because the return value is the hInstance for the instance of the application, which is running it its own address space. (An interesting side note: The hInstance value is the base address where the application's module was able to load: either the default address or the fixed up address.) In Win32, running several instances of the same application causes the instances to start and run in their own separate address space. To emphasize the difference: multiple instances of the same application on Windows 3.1 run in the same address space; in Win32 applications running on Windows NT or Windows 9x, each instance has its own, separate address space. Using an instance handle to uniquely identify an application instance, as is possible in Win16, does not apply in Win32. (Another interesting side note: Remember that even if there are multiple instances of an application, if they are able to load at their default virtual address spaces, the virtual address pages of the different applications' executable code will map to the same physical memory pages.) In Win32, instance handles are not unique in the global scope of the system; however, window handles, thread IDs, and process IDs are. Here are some calls that may assist in alternative methods to uniquely identify instance of applications on Windows NT: GetWindowThreadProcessID() retrieves the identifier of the thread that created the given window and, optionally, the identifier of the process that created the window. 
    OpenProcess() returns a handle to a process specified by a process ID. 
    GetCurrentProcessID() returns the calling process's ID. 
    EnumThreadWindows() returns all of the windows associated with a thread. 
    The FindWindow() function retrieves the handle of the top-level window specified by class name and window name. 
    Windows NT only: To enumerate all of the processes on the system, you can query the Registry using RegQueryValueEx() with key HKEY_PERFORMANCE_DATA, and the Registry database index associated with the database string "Process". 
    Windows NT 4.0 only: To enumerate all of the processes on the system, you can use the EnumProcesses PSAPI function. See the Platform SDK documentation for more information on EnumProcesses 
    Windows 95 and later, Windows 2000 and later: To enumerate all of the processes on the system, you can use the 32-bit Toolhelp APIs. See the Platform SDK documentation on the following APIs: CreateToolhelp32Snapshot, Process32First, and Process32Next 
    For further details on using these calls, please see the Platform SDK documentation. Additional query words: Keywords: kbOSWinNT kbOSWin2000 kbGrpDSUser kbOSWin 
    Issue Type: kbinfo 
    Technology: kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbWin32sSearch 
      

  13.   

    在win32中HINSTANCE和HMODULE的概念没什么本质区别进程加载的DLL的HINSTANCE(或称为HMODULE)仅仅和该DLL文件中的PE结构中的ImageBase属性有关,这个值在DLL被编译时就决定的,当ImageBase的值指向的内存地址已经被使用的话,操作系统会为这个DLL的基地址进行重定向,这将用到DLL文件中.reloc节,如果该DLL没有。reloc节,那么加载将失败