Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens to global variables declared in a DLL?

Tags:

c++

windows

dll

Let's say I write a DLL in C++, and declare a global object of a class with a non-trivial destructor. Will the destructor be called when the DLL is unloaded?

like image 432
Dima Avatar asked Sep 16 '08 18:09

Dima


People also ask

Why is it bad to declare global variables?

Using global variables causes very tight coupling of code. Using global variables causes namespace pollution. This may lead to unnecessarily reassigning a global value. Testing in programs using global variables can be a huge pain as it is difficult to decouple them when testing.

Are global variables permanent?

Global variables are created when the program starts, and destroyed when it ends.

Why global variables are declared static inside the library?

Global Variables in Library Source Files Static — use the static keyword to make a global variable visible only to functions within the same source file whenever possible. This removes any potential for conflict with variables of the same name in any other library source files or user application code.

Do global variables go on the heap?

Stack and heap are used to store variables during the execution of the program and it also get destroyed. Global data structures or global variables are not consumed by stack or heap. They basically allocated in a fixed memory block, which remains unchanged.


2 Answers

In a Windows C++ DLL, all global objects (including static members of classes) will be constructed just before the calling of the DllMain with DLL_PROCESS_ATTACH, and they will be destroyed just after the call of the DllMain with DLL_PROCESS_DETACH.

Now, you must consider three problems:

0 - Of course, global non-const objects are evil (but you already know that, so I'll avoid mentionning multithreading, locks, god-objects, etc.)

1 - The order of construction of objects or different compilation units (i.e. CPP files) is not guaranteed, so you can't hope the object A will be constructed before B if the two objects are instanciated in two different CPPs. This is important if B depends on A. The solution is to move all global objects in the same CPP file, as inside the same compilation unit, the order of instanciation of the objects will be the order of construction (and the inverse of the order of destruction)

2 - There are things that are forbidden to do in the DllMain. Those things are probably forbidden, too, in the constructors. So avoid locking something. See Raymond Chen's excellent blog on the subject:

  • Some reasons not to do anything scary in your DllMain
  • Another reason not to do anything scary in your DllMain: Inadvertent deadlock
  • Some reasons not to do anything scary in your DllMain, part 3

In this case, lazy initialization could be interesting: The classes remain in an "un-initialized" state (internal pointers are NULL, booleans are false, whatever) until you call one of their methods, at which point they'll initialize themselves. If you use those objects inside the main (or one of the main's descendant functions), you'll be ok because they will be called after execution of DllMain.

3 - Of course, if some global objects in DLL A depend on global objects in DLL B, you should be very very careful about DLL loading order, and thus dependancies. In this case, DLLs with direct or indirect circular dependancies will cause you an insane amount of headaches. The best solution is to break the circular dependancies.

P.S.: Note that in C++, constructor can throw, and you don't want an exception in the middle of a DLL loading, so be sure your global objects won't be using exception without a very, very good reason. As correctly written destructors are not authorized to throw, the DLL unloading should be ok in this case.

like image 144
paercebal Avatar answered Sep 19 '22 15:09

paercebal


This page from Microsoft goes into the details of DLL initialization and destruction of globals:
http://msdn.microsoft.com/en-us/library/988ye33t.aspx

like image 25
Mark Ransom Avatar answered Sep 22 '22 15:09

Mark Ransom