views:

456

answers:

5

Hi,

Our current application is a single OpenGL EXE containing multiple pages. The EXE is responsible for accessing data sent across the network via UDP. It accumulates the data and stores it in a host of singleton structures. The individual pages within the EXE access the singleton structures to process the data as they see fit.

In an attempt to lighten our EXE footprint and to support our attempts at configuration management, we have decided to split the pages out into a single DLL that the EXE will load. It is our intention to have the EXE be the shell into which the pages from the DLL will be loaded. The EXE will still have all communication responsibilities (UDP, Corba, User, etc). The pages will still be responsible for displaying whatever it is they do.

The question (finally) becomes: How do I pass this myriad of data collected from the EXE down to the consuming DLL based pages. The Singleton concept no longer holds water as the singletons we use (ACE_Singleton) do not allow this level of direction. We can export singletons from the DLL to the consuming EXE all day long, but I have yet to figure out the reverse. I have come up with the following options - none of which I like, so I was hoping someone out there would have a better one :)

  1. Wrap up all the data that is currently stored in separate singletons into another DLL that would export a "true" singleton. Eg. The singleton exported from the DLL would be the same - no matter what EXE loaded it - sort of like shared memory. This is an intriguing choice but would cause problems down the line with our deployment scenarios. I could go into detail about those issues if folks are really smitten with this idea.
  2. Create a static DLL level structure that contains all the pertinent data. The EXE would push this data down to the DLL upon DLL load so that the pages contained within the DLL would have access to the data. This seems like the simplest solution - even if it entails editing every single page in our application - over 100. It also seems a bit sloppy. All the data is just in a global. Not very sexy or C++y either.

So, anyone else out there have a solution for this problem?

The application is written using Visual C++ 9.0 (VisualStudio 2008) for use on Windows XP. For some reason Vista is not supported in our lab yet - even though our customers are using it.

A: 

You could either:

  • put everything bar the very outermost shell into a 'common' DLL;
  • use a DEF file to generate export functions from your EXE.

The second is very uncommon but it is possible to generate an import library just from the DEF file. Use LIB /DEF to generate the import library. See Working with Import Libraries and Export Files.

Mike Dimmick
A: 

Unfortunately, it sounds like you've got a lot of existing code to tinker with. In that case, I'd just go with (2), assuming it doesn't get too large and unwieldy.

From your description, it sounds like data at the EXE level only needs to be sent once on DLL load.

If (2) is too messy, I'd refactor it a little to have a base "DLLPage" class with Serialize/UnSerialize() functions. Never export the class itself, only the individual functions you need in it (this helps tremendously as the class changes... very weird breaks happen with class-level exports). You'll need the constructor/destructors, and probably every public member.

There could be some heap management issues, so I also like to overload new/delete and have all classes use a centralized new/delete located in a helper DLL.

darron
A: 

Before you take the plunge breaking the EXE up, you should read up on memory management and DLLs.

Here is one article that talks about CRT object issues, but the same thing applies to your own C++ objects.

Potential Errors Passing CRT Objects Across DLL Boundaries

Torlack
+1  A: 

Give all the DLLs a function SetGlobalDataPointer(Singleton*). Your EXE calls this function before it calls any other DLL function. In the DLL code, replace all occurances of theSingleton. by theSingletonPtr->

MSalters
A: 

First option: place all the data that the exe holds in shared memory. The dlls can then happily access it, as long as you have proper locking in place.

Second option: transfer the memory to the dlls using an exported function pointer - the exe has a function, the dll calls another function in the exe that returns this function as a pointer, which the dll can then call. That exported function can transfer data as a normal structure on the stack.

Third option: if you use the same runtime, just export a pointer that gives you direct access to the memory.

gbjbaanb