// RAII wrapper around a DLL.
class DynamicLibrary
{
public:
template<typename T>
DynamicLibrary(const T* name) :
_handle(LoadLibrary(name))
{
if(_handle == 0)
throw DynamicLibraryException();
}
~DynamicLibrary()
{
FreeLibrary(_handle);
}
template<typename T>
T GetSymbol(const char* name)
{
return reinterpret_cast<T>(GetProcAddress(_handle, name));
}
private:
HMODULE _handle;
};
Library semantics
Suppose we have a class:
Typically, the user either:
a. loads the DLL in question temporarily, calls a function, gets rid of it
b. loads a bunch of DLLs for quite awhile (plug-ins) and unloads them much later
b. is probably more prevalent than a. The question is, how do I accomodate the second case gracefully? Because this is little more than a RAII wrapper, they can't just throw it inside a container. "Use reference counted pointers" you say. Well, maybe. Like I said in another post, it seems kind of silly to dynamically allocate memory just to get a little more control over the lifetime of the object. Technically, I could use a non-const copy constructor to hand off ownership until the last instance bites the dust, but I gathered this isn't entirely kosher (from my discussion on auto_ptrs earlier).
The only thing I can think of is to change the class to a DLL container.
This would give you a bunch of DLL's that are freed when the instance of the container is destroyed instead.
Not the best solution though...I would use smart ptrs...=)
This would give you a bunch of DLL's that are freed when the instance of the container is destroyed instead.
Not the best solution though...I would use smart ptrs...=)
class DynamicLibraryContainer{public:typedef DLLHandle int;DLLHandle LoadDLL(const char *name){ HMODULE handle = LoadLibrary(name); if(handle == 0) throw DynamicLibraryException(); if('_handles' does not contain 'handle') _handles.push_back(handle); return 'index to handle';}~DynamicLibraryContainer(){ FreeLibrary(_handles[0..n]);}template<typename T>T GetSymbol(DLLHandle, const char* name){ return reinterpret_cast<T>(GetProcAddress(_handles[DLLHandle], name));}private:vector<HMODULE> _handles;};
There really is no difference between your two cases: its all a question of scope. If you want to load a dll for a plugin then you just keep the DynamicLib class alive for the duration that the plugin is required for. IIRC there is no problem in obtaining multiple handles to the same DLL - windows will simply do the reference counting behind the scenes as it has to do reference counting of DLL's across the whole system anyway.
BTW why is your constructor templated? LoadLibrary takes const char array as its argument and so you should simply have a single constructor.
Its also a good idea to make the copy constructor private to disallow copy construction as that will break the RAII idiom.
James
BTW why is your constructor templated? LoadLibrary takes const char array as its argument and so you should simply have a single constructor.
Its also a good idea to make the copy constructor private to disallow copy construction as that will break the RAII idiom.
James
Quote:If you want to load a dll for a plugin then you just keep the DynamicLib class alive for the duration that the plugin is required for
This is the problem. How do you keep a bunch of dynamically loaded DLLs in scope with antareus approach (without dynamic allocation of each instance)? If you push them in a container they will be copied. Of course, it's possible to push an empty instance first, and then call Load on it or something...
I guess this is a general thought about RAII, so the fact that windows handles ref counting in this case is irrelevant.
Thanks for the responses.
That should have been a TCHAR. My mistake.
As for the intrusive reference counting idea, I will go with that approach. Thanks!
Quote:BTW why is your constructor templated? LoadLibrary takes const char array as its argument and so you should simply have a single constructor.
That should have been a TCHAR. My mistake.
As for the intrusive reference counting idea, I will go with that approach. Thanks!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement