Dynamically loaded DLLs and instances

Started by
3 comments, last by Nypyren 10 years, 4 months ago

Hey guys,

Let's say I have an App which uses a Lib which is a DLL. The Lib is linked to the App at compile time with the help of a linker library (.lib) file, so the App automatically loads the Lib upon startup.

Now imagine I have a Plugin which is also a DLL. It also uses the Lib DLL in the exact same way as the App does. The Plugin is not linked to anything at compile time. Instead the Lib DLL loads it dynamically (through LoadLibrary()) when it is loaded by the App.

My question is, is the DLL instance of Lib the same for the App and the Plugin? Eg. if I have a singleton in the Lib DLL, will it be the same for the App and the Plugin?

Cheerios!

Advertisement
A Windows dll is basically a separate program, each one runs DllMain() when it is started, and there is very limited sharing that can take place between your app and the library. Only a few data types can easily cross the dll boundary, and there are many template classes that cannot cross that boundary at all. If you export a variable then behind the scenes it just hooks up an interface for you.

If you have a singleton (or more properly, a static object instance) in your library it will remain inside that instance of the library. If you load a second library and it has a static object instance as well, then each will have their own instances.

There are methods to hook up shared memory between the three, but it generally isn't recommended. Shared mutable state tends to get nasty really quickly in most situations, which is one of many reasons singletons are typically a bad approach to a problem.

Hmm.

I have had no problems exporting classes and data from DLLs before. In my current setup my game loads an engine DLL which just dllexports whole classes and it works just fine. There are also singletons created on the DLL side and both the engine and the game can access that instance just fine. Do you see any problems with this? I know there are limitations but none so far have been deal breakers for me. My template classes are usually header-only, so they are not exported from the DLL per sé, but #included in the game where needed.

As for my original question, I am trying to figure out how the Ogre rendering engine does its plugin loading, and so far it seems to work pretty much like I described in the OP. However, I am still unsure how the different parts of the system access the one and only Ogre main DLL. I could offcourse ask in the Ogre forums, but I was thinking about this on a more general level...

While frob is correct, there are some missing details which are important. STL for instance is completely usable over libraries if "ALL" items link to a dynamic (and the same) form of msvcrt. All executables, dlls etc, must use "dynamic link" to msvcrt and at that point it is completely viable to use all of C++ std without issue over DLL's. The key bit of difficulty with Windows is that things *can* run in different memory spaces even from within the same process. If everything shares the same msvcrt (must be the dll version), all the memory issues go away because the msvcrt basically defines "the memory space". (For the most part, there are *other* issues of course.)

In general though, this is a fine way to do things if you intend to be cross platform. It solves all the memory issues which vary from Windows to just about any other platform. It is a fairly common practice for most 3rd party items to supply appropriate dll's for this centralized msvcrt linkage etc. The performance cost is pretty much unmeasurable so who cares.

For those interested, the details are pretty simple. Msvcrt implements a memory manager with a singleton. Yup, the evil singleton strikes and in this case it can be a nightmare. You can link to msvcrt either dynamically or statically. *if* everything uses dynamic linkage, everything gets the same singleton. If there is any mixed usage, things blow up quickly because there are multiple memory managers which don't know about each other.

Hope this clarifies things a bit from the Windows unique view.

This particular link contains most of the information I was going to type out, so I'll just put it here instead:

http://stackoverflow.com/questions/4911994/sharing-a-global-static-variable-between-a-process-and-dll

Short summary:
- "dllimport/dllexport" static variables will resolve themselves using the typical loader mechanisms as long as only ONE DLL exports a given variable and ALL other EXEs/DLLs which use the variable import it instead of statically link to it.
- All other static variables get their own instance in each module (EXE or DLL) that statically linked them and will not be shared, which can cause issues.

My question is, is the DLL instance of Lib the same for the App and the Plugin? Eg. if I have a singleton in the Lib DLL, will it be the same for the App and the Plugin?


In your particualar case, the EXE and DLL will both get a separate singleton, not a shared one. To fix this, you would need a third DLL which exports the static variable or a function to access it. The EXE and plugin DLLs can then dynamically link to that plugin-helper DLL just fine.

In .Net, for plugin support, you can provide public classes/variables in the EXE and reference the EXE when building a plugin DLL. The EXE *must* load these kinds of DLLs manually otherwise a cyclic build-time dependency forms. This may be possible in C/C++ EXEs if dllexport is allowed, but I haven't personally tried it.

This topic is closed to new replies.

Advertisement