How can I ensure a dll is not unloaded while any objects in it exist?
The problem is, when I was using explict memory management I could delete the dll objects before freeing the dll, however with smart pointers I have no controll over the order there destroyed, meaning the dll may be freed first causeing a crash when trying to free one of the other objects:
FlPtr is a simple refrence counting class thats calls AddRef and Release as needed
ExampleDll *dll = LoadDll(L"bin\\example.dll");
IObject *obj = dll->CreateObject();
...
obj->Release();
delete dll;//fine because all objects already deleted
return 0;
auto_ptr<ExampleDll> dll = LoadDll(L"bin\\example.dll");
FlPtr<IObject> obj = dll->CreateObject();
...
return 0;//crash if dll is destructed before obj since Object::Release needs to call into the dll
I tried making the dll handle unloading itsself, ie only unload after all objects have been deleted. This work by creating a new object IExampleDll which the dll implements. This is like the ExampleDll object from before but lives in the dll rather than the exe and is also refrence counted. Each object in the dll increments this refrence on contruction and deincrements it on destruction. This means the refrence count only reaches zero when the exe has Released its refrences AND all the dlls objects have been destroyed. It then deletes itsself calling FreeLibrary(GetModuleHandle()) in its destructor.
This however crashes at the FreeLibrary, im asuming because the thread is still in the dlls code that is being unloaded...
I'm at a loss now how to make sure the dll is only unloaded when there are no remaining objects, apart from going back to freeing the dll explicitly after everything else should have been deleted;
int main()
{
ExampleDll *dll = LoadDll("bin\\example.dll");
restOfProgram();
delete dll;
}
This approach becomes difficult when dlls need to be loaded/unloaded mid program saftly, ie if the user changed from d3d to openGL in options.