0
votes

I did solve my immediate problem at hand, but now I need to understand why it is solved. ;-)

So here I have couple more questions.

Suppose I have a class that is being exported from the DLL. Now this DLL should be loaded into the memory every time I call:

MyExportedClass *pb = new MyExportedClass;

and it should stay in memory and becomes unloaded only when I call:

delete pb;

Is this correct?

If I understood this correctly and the answer to the previous question is yes, then what should happen in the following scenario:

I have an interface which exported from the dll (dll1) and I have its implementation which is exported from another dll (dll2). So every time I execute:

MyInterface *pInterface = new MyImplementation;

both those dlls should be loaded in memory and they should stay in memory until I call:

delete pInterface;

Is this correct?

Now, if the answer to this question is yes - do I have a control/saying, which library will be unloaded first and which one will be second? Or the unload will always happen right after calling destructor of the appropriate class?

Now, is there a tool which checks if the library becomes unloaded and at which point? I can probably just use the fake DllMain() and check its process_detach case, but my impression always was: use DllMain when the library exports function and don't use DllMain when the library exports classes. I used this approach since MSVC 5/6 (following one of the books about C++).

Was I wrong and I can still use DLLMain in both cases?

Thank you.

1
Why do you think that every instantation/destruction of an object does the same for the whole DLL? - deviantfan
My understanding of operating systems says that a DLL is only unloaded from memory when the memory is needed (by another DLL, program, etc.). Deleting an object does not force the unloading of a DLL. - Thomas Matthews
@deviantfan, not sure what you mean. Could you elaborate please? - Igor
@ThomasMatthews, but then when the DLL becomes unloaded we will have a dangling pointer, right? I mean the object can be calling the function, but without the dll being present it will just crash. That is unless I'm missing something and the dll will load itself by OS in this case. - Igor
not sure what you mean I mean that the answer for your first Is this correct? in the question is No. And the rest makes no sense anymore because of that. - deviantfan

1 Answers

1
votes

DLL loading can be automatic (if listed in the import table) or manual (using LoadLibrary). Some managed frameworks, like .NET, will silently call LoadLibrary for you when they see a DLL import declaration in their metadata, but C++ is not one of these. The closest thing C++ has is delay-loading, where the function that calls LoadLibrary is (by default, you can substitute your own) provided by the compiler.

On the other hand, DLL unloading is always manual. Deleting an object never implicitly unloads a DLL. You have to call FreeLibrary (or FreeLibraryAndExitThread). And you had better not call FreeLibrary while objects defined in that library are still in use.

Now, the COM system in Windows is a bit more complicated, because it manages DLL lifetime for you. But DLL lifetime is still not controlled by object deletion, rather by calling a DllCanUnloadNow function in the DLL. Usually you need to maintain a count of active objects in order to write that function correctly. But it still requires your manual implementation, and you can simply always return false to never unload (this is a bit of a pain during development because you have to close the entire application to try a new plugin version, etc... but actually freeing every usage of a DLL and successfully unloading it is rare anyway)

And certainly there is nothing that will automatically unload a DLL listed in the import table, those get loaded during process startup and never unloaded, no matter how many object instances are created or destroyed.