Я пытаюсь создать простую Win32 DLL. В качестве интерфейса между DLL и EXE я использую функции C, но внутри DLL я использую объект C ++ singleton. Ниже приведен пример моей реализации DLL:
// Файл MyDLLInterface.cpp --------------------
#include "stdafx.h"
#include <memory>
#include "MyDLLInterface.h"
class MySingleton
{
friend class std::auto_ptr< MySingleton >;
static std::auto_ptr< MySingleton > m_pInstance;
MySingleton()
{
m_pName = new char[32];
strcpy(m_pName, “MySingleton”);
}
virtual ~ MySingleton()
{
delete [] m_pName;
}
MySingleton(const MySingleton&);
MySingleton& operator=(const MySingleton&);
public:
static MySingleton* Instance()
{
if (!m_pInstance.get())
m_pInstance.reset(new MySingleton);
return m_pInstance.get();
}
static void Delete()
{
m_pInstance.reset(0);
}
void Function() {}
private:
char* m_pName;
};
std::auto_ptr<MySingleton> MySingleton::m_pInstance(0);
void MyInterfaceFunction()
{
MySingleton::Instance()->Function();
}
void MyInterfaceUninitialize()
{
MySingleton::Delete();
}
// файл MyDLLInterface.h --------------------
#if defined(MY_DLL)
#define MY_DLL_EXPORT __declspec(dllexport)
#else
#define MY_DLL_EXPORT __declspec(dllimport)
#endif
MY_DLL_EXPORT void MyInterfaceFunction();
MY_DLL_EXPORT void MyInterfaceUninitialize();
Проблема или вопрос, который у меня есть, следующие: Если я не вызов MyInterfaceUninitialize () из моих EXE-файлов ExitInstance () , у меня есть утечка памяти (указатель m_pName ). Почему это происходит? Похоже, что уничтожение MySingleton происходит после выхода EXE. Можно ли заставить DLL или EXE уничтожить MySingleton чуть раньше, поэтому мне не нужно вызывать MyInterfaceUninitialize () функцию?
EDIT:
Спасибо за вашу помощь и объяснения. Теперь я понимаю, что это проблема дизайна. Если я хочу остаться с моим текущим решением, мне нужно вызвать функцию MyInterfaceUninitialize () в моем EXE. Если я этого не делаю, это тоже нормально, потому что синглтон уничтожает себя, когда покидает область действия EXE (но мне нужно жить с тревожными сообщениями отладчика). Единственный способ избежать такого поведения - переосмыслить всю реализацию.
Я также могу установить свою DLL как «Delay Loaded DLLs» в Linker-> Input в Visual Studio, чтобы избавиться от тревожных сообщений отладчика.