views:

335

answers:

3

I’m trying to create a simple Win32 DLL. As interface between DLL and EXE I use C functions, but inside of DLL i use C++ singleton object. Following is an example of my DLL implementation:

// MyDLLInterface.cpp file --------------------

#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 file --------------------

#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();

The problem or the question that i have is following: If i don't call MyInterfaceUninitialize() from my EXEs ExitInstance(), i have a memory leak (*m_pName* pointer). Why does it happening? It looks like the destruction off MySingleton happens after EXEs exit. Is it possible to force the DLL or EXE to destroy the MySingleton a little bit earlier, so I don't need to call MyInterfaceUninitialize() function?

EDIT: Thanks for all your help and explanation. Now i understand that this is a design issue. If i want to stay with my current solution, i need to call MyInterfaceUninitialize() function in my EXE. If i don't do it, it also OK, because the singleton destroys itself, when it leaves the EXE scope (but i need to live with disturbing debugger messages). The only way to avoid this behavior, is to rethink the whole implementation.

I can also set my DLL as "Delay Loaded DLLs" under Linker->Input in Visual Studio, to get rid of disturbing debugger messages.

+2  A: 

You can take advantage of the DllMain callback function to take appropriate action when the DLL is loaded/unloaded or a process/thread attaches/detaches. You could then allocate objects per attached process/thread instead of using a singleton since this callback function is executed in the context of the attached thread. With that in mind, also take a look at Thread Local Storage (TLS).

Judge Maygarden
Thanks! I will try it.
mem64k
Note the warning from MSDN: "There are serious limits on what you can do in a DLL entry point. To provide more complex initialization, create an initialization routine for the DLL. You can require applications to call the initialization routine before calling any other routines in the DLL."
dalle
@dalle: Yes! This is also my concern. I'm not sure, if it will complicate my interface.
mem64k
+3  A: 

If i don't call MyInterfaceUninitialize() from my EXEs ExitInstance(), i have a memory leak (*m_pName* pointer). Why does it happening?

This is not a leak, this is the way auto_ptrs are supposed to work. They release the instance when they go out of scope (which in your case is when the dll is unloaded).

It looks like the destruction off MySingleton happens after EXEs exit.

Yes.

Is it possible to force the DLL or EXE to destroy the MySingleton a little bit earlier, so I don't need to call MyInterfaceUninitialize() function?

Not without calling this function.

dirkgently
Thanks for your confirmation! Do you know any trick or workaround?
mem64k
Singleton's are basically global objects, how would you expect say, a global `int` object to behave w.r.t lifetime? It won't be any different. If you are really concerned about the order in which memory is freed for your objects try a different design (e.g: pass around the state instead of using a singleton).
dirkgently
+1  A: 

Honestly, for the example you gave, it doesn't matter if you call the Uninitialize method from your ExitInstance. Yes, the debugger will complain about the unreleased memory, but then again, it's a singleton, it's intended to live for an extended duration.

Only if you have some state information in the DLL that needs to be persisted at exit, or if you are dynamically loading/unloading DLLs multiple times, do you need to be diligent about cleaning up. Otherwise, just letting the OS tear down the process at exit is just fine, the reported memory leak is inconsequential at that point.

JMcDaniel
@JMcDaniel: Yea, I understand how it works. But i wondering, if there exists any clean solution for this issue.
mem64k
Is the issue the reported memory leak, or just a clean way to unload DLL modules? As pointed out below, the DLLMain mechanism is about as close as you are going to come to an automated un-init hook point.
JMcDaniel