Как я могу убедиться, что dll не выгружена, когда в ней есть какие-либо объекты?
Проблема в том, что когда я использовал явное управление памятью, я мог удалить объекты dll перед освобождением dll, однако с помощью умных указателей я не имею никакого контроля над порядком уничтожения, то есть dll может быть освобожден первым, вызывая сбой, когда пытаясь освободить один из других объектов:
FlPtr - это простой класс подсчета ссылок, который при необходимости вызывает AddRef и Release
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
Я пытался заставить dll-дескриптор выгружаться сам, то есть выгружаться только после удаления всех объектов. Эта работа путем создания нового объекта IExampleDll, который реализует DLL. Это похоже на объект ExampleDll из предыдущего, но живет в dll, а не в exe, и также считается ссылкой. Каждый объект в dll увеличивает это значение при конструировании и увеличивает его при разрушении. Это означает, что счетчик ссылок достигает нуля только тогда, когда exe выпустил свои ссылки и все объекты dll были уничтожены. Затем он удаляет себя, вызывая FreeLibrary (GetModuleHandle ()) в своем деструкторе.
Это, однако, происходит сбой во FreeLibrary, я предполагаю, что поток все еще находится в выгружаемом коде dll ...
Теперь я в растерянности, как убедиться, что dll выгружается только тогда, когда нет оставшихся объектов, кроме как вернуться к освобождению dll явно после того, как все остальное должно было быть удалено;
int main()
{
ExampleDll *dll = LoadDll("bin\\example.dll");
restOfProgram();
delete dll;
}
Этот подход становится трудным, когда библиотеки dll должны загружаться / выгружаться в середине программы, т. Е. Если пользователь перешел с d3d на openGL в опциях.