How to force the order of destruction of static objects in different dlls?

I have 2 static objects in 2 different dlls :

The Resources object (which is a singleton) and the User object. Object The user in his destructor must access the resources of the object.

How to make the Resources object not be deleted before the User object?

+4
source share
4 answers

Global objects are destroyed when their corresponding DLL is unloaded. Since your "User" dll probably depends on your DLL resource, you are having problems: the "resource" will always be destroyed before the "user".

I am also interested in a good answer to this question, if one exists. Until now, I use the cleanup function, which must be called by the application before it is released, and I save the harmless code in the destructors.

+2
source

If you can put 2 global variables in the same DLL, this is not the same story. As Jem said in his own answer, the DLL debugging system is not guaranteed by the system. Therefore, you may have a big problem with 2 separated Dlls. I am not a Windows system guru, but looking using google I found msdn bloggers which says that they had the same problem and there was no good solution to solve it.

I can put them in one DLL, in my opinion, the solution is simpler, in this case you do not need to solve the problem of "not guaranteed answer to the DLL" (it’s not solvable, as I understand it).
But then you still need to solve a new problem: the global order of destruction of variables is not guaranteed by the C ++ language. But this can be solved:

you need to use some kind of reference couting. boost :: shared_ptr can do the trick.

Declare it global and define it as follows:

boost::shared_ptr my_resource_ptr ( new Resource() ); // new operator is important here! 

Then you need to change your user implementation to keep your own shared_ptr:

 class User { ... boost::share_ptr a_resource_ptr; ... }; 

Until the entire user instance is destroyed, they will β€œsave” the Resource instance and thus prevent it from being deleted from the environment, even if the global shared_ptr could be destroyed. The last destroyed instance of the user (indirectly) will delete the instance of the resource.

Regardless of the reference count used, ComPtr is your own, it should do the trick.

+3
source

I do not think that you can change the order of destruction of globals located in different modules. Is it likely to add reference counting?

+1
source

In case you really want to get 2 separate Dlls, I may have some tips for you: you can consider using FreeLibrary() from the Windows API. As indicated by msdn, FreeLibrary() decreases the reference counter for the Dll, which is unloaded when the counter reaches 0.

Disadvantage: using FreeLibrary() implies that you load it using LoadLibrary() ( msdn link ), and a call function from this library implies that you use the GetProcAddress() function, which can lead to really ugly code. And this may mean some changes in your code - like getting a global variable for Dll functions to save the address of each function ...

If you want to implement it:

  • you must load and free the library from your main() function of your process,
  • as well as loading and freeing the library from the Dll that implements the User class. Add it to the DllMain() function for this Dll when the reason is DLL_PROCESS_DETACH (see mdsn DllMain link .

Thus, he will unload the Resource library only after the User library has finished with it.

Try it if you want and let me know if it works, since I never implemented it.

Ps: I put the second answer to your question in order to get a meaningful separation between the two answers, as I will (try) to detail both of them. I do not want you to mix them up and confuse ...

+1
source

All Articles