FreeLibrary doesn't unload the DLL

1
2
3
4
5
6
7
8
9
10
11
int main()
{
	HMODULE md = LoadLibrary("my_dll.dll");
	FreeLibrary(md);

	if (GetModuleHandle("my_dll.dll") != 0)
	{
		return 1;
	}
	return 0;
}


So I've got this simple code above. I expect it to return 0 however it's returning 1. I've read that there's a reference count which is increased with every LoadLibrary call and decreased with every FreeLibrary call and the module should be freed when that number has reached 0. Am I missing something?

Edit:

I noticed that when I change the dll name from 'my_dll' to something else it's returning 0. Does that mean that 'my_dll' is bugged? Any chance to fix it besides restarting my computer?
Last edited on
From the "Remarks" section at https://msdn.microsoft.com/en-us/library/windows/desktop/ms683152(v=vs.85).aspx :
The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary.


Perhaps the reference count isn't 0 to begin with.
Thanks for the answer. GetModuleHandle("my_dll.dll") returns 0 before I call the LoadLibrary. I've restarted my system but the issue still persists.
Restarting your system won't change anything, why do you think it would make a difference?

Instead of asking us how to force unload the DLL, can you tell us what you exactly plan on doing? Since unloading a DLL can cause the program more bad than good (e.g. if the DLL you unloaded set API hooks then the callback addresses will no longer exist in memory so when the hooked function is called it'll cause an Access Violation).

If you elaborate what you're trying to do, we may be able to provide a better alternate solution with test code which is much safer... DLLs are not meant to be unloaded by default.
Try this code, maybe you get some error msg.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <Windows.h>
#include <iostream>
#include <string>

class Win_error 
{
private:
  std::string m_what;
public:
  Win_error()
  {
    LPVOID lpMsgBuf;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM |
      FORMAT_MESSAGE_IGNORE_INSERTS,
      NULL, GetLastError(), 0,
      (LPTSTR) &lpMsgBuf, 0, NULL);
    m_what.assign((const char *) lpMsgBuf);
    LocalFree(lpMsgBuf);
  }
  const char* what()const
  {
    return m_what.c_str();
  }
};

void Test()
{
  HMODULE md = LoadLibrary("my_dll.dll");
  if (md == INVALID_HANDLE_VALUE)
    throw Win_error();

  if (!FreeLibrary(md))
    throw Win_error();

  if (GetModuleHandle("my_dll.dll") == 0)
    throw Win_error();
}

int main()
{
  try
  {
    Test();
    std::cout << "** Everything ok **";
  }
  catch (Win_error& we)
  {
    std::cerr << "\a" << we.what() << "\n\n";
  }
  system("pause");
  return 0;
}
Windows (as do all operating systems) naturally has internal 'garbage collection' or memory reclamation services which run more intensively the higher the memory stress on the system. The internal and proprietary implementation of FreeLibrary() might be such that it simply marks a process dll as unused, i.e., sets its reference count to zero, without actually unloading it.

I've run into that situation in the COM/OLE coding I do. In many cases when the reference count on the object reaches zero object destruction code doesn't immediately run. The reason I know this is because in the development of the code for both client and COM/OLE object I'm logging function calls and values to internal log files. Oftentimes I need to call CoFreeUnusedLibraries() which finally triggers object unloading/destruction code.
Topic archived. No new replies allowed.