Today I helped the developer of the Georges Editor Qt rewrite with a curious problem - one which I have written about here in the past in more detail. He created an Object Viewer Qt widget plugin that he could load using Qt's tools and thus promote from within Qt Designer/Creator. This makes perfect sense and doesn't violate any notion of the usage of NeL. Except that he isn't loading the DLL using NeL's CLibrary class - he's loading it using QPluginLoader instead. Due to the nature of address relocation in Windows he predictably ran into problems: folders he added to NLMISC::CPath in his main application where not available in his library and he couldn't determine why.
The correct fix is to load the library as a Pure NeL Library. However due to the fact that he wanted this to be a Qt plugin and widget converting the loading to NeL's was not an option. So I suggested that he create a not-so-pure NeL Library by manually passing the application context rather than relying on the the NeL loader. Here's how we did it:
Now one thing that is important to note is that we implemented the setter method in the source file and not in the header. If the header is included into a source file in the implementing application then it will be duplicated in that address space thus throwing erroneous exceptions via the nlassert to check if the context is initialized. If somehow the call to the method doesn't assert it also will not accomplish what is necessary - the implementation must be in a source code file in the library that is being loaded.
A quick summary of what we did and what is happening: we added a new member to a class in the DLL call _LibContext which is a CLibraryContext. We then added a method that exists in the DLL's address space that allows the loading application to call and set this _LibContext value with its own context. Then after loading the DLL using Qt's loader we manually populate the library's context using the local CApplicationContext thruogh the context interface.
All of the NeL singletons, such as CPath, are safe signletons which means that their references are tracked in the application context. On Windows the lack of address relocation is compounded by the fact that NLMISC is statically linked to all implementing binaries. DLLs are considered binaries for sake of this argument. We pass the application context containing the references to the actual singletons to downstream libraries so that calls to it are effectively re-routed to the instance instantiated in the application.