From: Vladimir Prus (ghost_at_[hidden])
Date: 2004-07-28 07:04:49
Reece Dunn wrote:
> In COM the object is responsible for keeping the DLL alive (via a
> reference count on the DLL as has been mentioned in other posts). If
> there are two objects from the DLL alive, then the DLL's reference
> count is two (unless it is explicitly locked to keep it alive).
> The MS documentation on DllMain says:
> During initial process startup or after a call to LoadLibrary, the
> system scans the list of
> loaded DLLs for the process. For each DLL that has not already been
> called with the
> DLL_PROCESS_ATTACH value, the system calls the DLL's entry-point
> Thus, if the DLL is already loaded by a process, it will not reload it
> on successive calls to LoadLibrary.
Just like in Linux. Good.
> The documentation on FreeLibrary says:
> The FreeLibrary function decrements the reference count of the
> loaded dynamic-link
> library (DLL). When the reference count reaches zero, the module is
> unmapped from
> the address space of the calling process and the handle is no longer
> Thus, there is no easy way to reload a DLL. The best solution would be
> to release the instance of the plugin you have loaded and let the
> system unload the DLL. It is best to only be concerned about the DLL
> when loading the plugin.
I think if we assume the all plugin work will be done only via the
library, then reloading DLL is simple. The "dll_handle" keeps the real
OS-dependent handle. The "dll_handle" is only created via static 'get'
method, which checks if the same DLL is already opened. It if it, it
just returns already existing dll_handle. So, OS reference count for
each DLL will be 1.
When you want to reload DLL, you close the OS handle and open the
library again. After that, you notify everybody who's interested.
The only question is how to detect that a library is already opened. On
Linux and it seems on Windows too, if you try to open library twice,
then you get back the same handle. So, "dll_handle::get" can work by:
- opening the library
- checking if the handle is already known (and so dll_handle instance
exists for it)
- if instance already exist, the new handle is closed to keep reference
count at 1
> If you want to alter plugins at run-time (e.g. removing or adding a
> plugin), just remove all references to the plugin to delete it or load
> the plugin into the plugin map from the DLL.
But if you know that some DLL has just changed, and want to reaload it,
you'd have to find all plugins which originate from that DLL,
and delete them. This might be invenient if you have several separate