Wie kann ich sicherstellen, dass eine DLL nicht entladen wird, während irgendwelche Objekte vorhanden sind?C++: Dll Entladen Problem
Das Problem ist, wenn ich explizite Speicherverwaltung verwendete, konnte ich die Dll-Objekte vor dem Löschen der DLL löschen, aber mit intelligenten Zeigern habe ich keine Kontrolle über die Reihenfolge zerstört, was bedeutet, dass die DLL zuerst freigegeben werden kann, verursacht einen Absturz wenn sie versuchen, eine der anderen Objekte zu befreien:
FlPtr ist eine einfache, das ist refrence Zählklasse ruft AddRef und Release als
benötigtExampleDll *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
ich habe versucht, die dLL Griff machen itsself Entladen, also erst nach allen Objekten entladen wurden gelöscht. Dies funktioniert, indem Sie ein neues Objekt, IExampleDll, erstellen, das von der DLL implementiert wird. Dies ist wie das ExampleDll-Objekt von vor, aber lebt in der DLL und nicht in der exe und wird auch reference gezählt. Jedes Objekt in der DLL erhöht diese Referenz auf die Konstruktion und dekrementiert sie bei der Zerstörung. Dies bedeutet, dass die Referenzenzählung nur Null erreicht, wenn die exe ihre refrences freigegeben hat und alle dlls-Objekte zerstört wurden. Es löscht dann selbst FreeLibrary (GetModuleHandle()) in seinem Destruktor.
Dies ist jedoch bei der Free abstürzt, im asuming weil der Faden noch im dlls Code ist, entladen wird ...
ich ratlos bin jetzt, wie man sicherstellen, dass die dll nur entladen werden, wenn Es gibt keine verbleibenden Objekte, abgesehen davon, dass die dll explizit freigegeben wird, nachdem alles andere gelöscht werden sollte.
int main()
{
ExampleDll *dll = LoadDll("bin\\example.dll");
restOfProgram();
delete dll;
}
Dieser Ansatz wird schwierig, wenn Dlls müssen saftly geladen/entladen Mitte Programm werden, das heißt, wenn der Benutzer von d3d geändert in Optionen OPENGL.
Ok Ich hatte einen Gedanken, was ist, wenn die Dlls Release() -Methode einen bool zurückgegeben hat, false, wenn es keine verbleibenden refrences gab, konnte die spezielle DllPtr freie Bibliothek aufrufen, wenn Release falsch zurückgegeben –
Aber das hat immer noch das Problem der letzten refrence wird in der dll gelöscht, wenn die DllPtrs zuerst gelöscht werden ... Wie würde ich den COM-Ansatz implementieren, so dass ich weiterhin die dll abfragen kann, nachdem der Stack und statische (dh globals) zerstört wurden, denn nur dann wird es dort garunteed keine ref? –
Sie benötigen eine Art "sauberer" Objekt, das nicht in der DLL enthalten ist, die Sie entladen, um eine solche DLL erfolgreich zu entladen. Dies ist ungefähr das, was ole32.dll tut, wenn CoUnitialize aufgerufen wird. – Ismael