Please help me sort out the following doubts on dlls on win32 platform.
1)A process calling loadlibrary() API loads the dll from the disk to the memory(to its address space),if another process now calls the API again with the same path to the dll as earlier, will the dll be loaded again from the disk to a new adress in the second process' address space?Or the previously loaded dll be reused?
For the documentation pertaining to Windows CE(i dont know what it is) msdn says that a reloading the dll is not required.Is the behaviour different for normal win32?
2)If there are no multiple loads of the dll, then doing a FreeLibrary() from one process may affect the other process which might be using the dll at that point of time.So is it the responsibility of the developer to maintain a ref counting mechanism for the dll(in form of some global varible in the dll) and check the ref count before freeing a dll?
3)If there are multiple loads then how do things work in the COM scenario?
Because there is a ref count maintained for the COM dll loaded and used by two differnt processes.Once the ref count drops to zero the com library frees the dll from the memory.
This means that there is only one COM dll instance present in the memory if two processes use the same component.
How is this made possible coz internally COM implementation also uses loadlibrary to load the COM dll?
1) A copy of the dll will be mapped into each process space. Unlike Win16, the dll will not be shared (i.e. reused).
1a) You'll need to implicitly link to or do a loadlibrary on the dll in each process.
2) When you are done with a dll loaded with LoadLibrary, call FreeLibrary when the reference count goes to zero (for the process), the dll will be unloaded. LoadLibrary/FreeLibrary calls in one process don't effect another process.
3) There are two types of COM servers: in-proc server and out of process servers. In proc servers are loaded into the process space. When their reference count goes to zero they are unloaded. Like 2) above, the COM reference count of an inproc server doesn't effect the same COM inproc server loaded into another process. Out-of-process COM servers are hosted by an exe. As such the reference count is shared across multiple process that load the COM object. In the out-of-process com server, the COM subsystem will terminate (or close) the exe only after all process have called Release on all the COM objects hosted by the server.
In general the data held by a dll loaded into a process is kept separate from the data in the same dll loaded into another process. The exception to this is data that is shared memory section data. In addition, a dll can also shared data by using one of the interprocess communication techniques such as memory mapped files or named pipes.
Thanks a lot for your replies guys.
Arjay,I still have a doubt, If a COM dll behaves the same way as a normal Dll as far as loading into multiple processes is concerned(i.e. multiple instances of it is loaded for multiple processes), then what is the need of maintaining a global reference count for the dll object and functions like "DllCanUnloadNow" because Windows itself takes care of monitoring the usage of a dll per process and unloading them when its no more in use by the process.?
The reference count is different for out-of-proc servers vs. in-proc servers. For out-of-proc servers (an exe), the COM subsystem will shutdown the exe server when all references (in all client processes have been released).
For an in-proc server, the reference count is only relevant for that process only and the COM server dll can be unloaded when the reference count reaches zero. However, another process could be loading the same in-proc COM server and that dll will definitely not be unloaded.
You can verify this yourself by creating a in-proc COM server and a couple of test applications. Load up the COM objects in each test application, call AddRef() on an interface, and then in one of the applications call Release(). Next call CoFreeUnusedLibrariesEx() api (and be sure to read the comments in the msdn docs with regard to unloading delays based on the threading model).
I would expect that only the application that has called Release() on the interface will unload the dll (after the specified time delay); whereas the same COM server dll loaded in the other process will still be in memory.
You can check if the COM server dll has been unloaded by calling tasklist on the process id. For example
tasklist /m /FI "PID eq 1756"
will display the list of loaded modules for processID 1756.
If the COM server dll has been unloaded, it won't appear in this list.