Wednesday, November 14, 2007

How to share data between different instances of DLLs

Setting up a shared data segment in a DLL. A shared data segment is used when you want to share variable values among several exe's. This is not as clever as a semaphore and not as powerful as a COM Event_Sink_MAP. However, it has very little overhead and it is very simple to implement. It is worth while knowing things can be done this easy.

One advantage of using a DLL is that several processes (exe's) can share a code segment. They share the code segment but each process gets it's own data segment. Therefore if five processes use a DLL there is only one code segment and five data segments.
What is a shared data segment?
A data segment is a chunk of main memory that holds the programs variables. It is the thing that gets swapped to the swap file.

A shared data segment in a DLL is simply one or more variables that are not unique to a specific process. In many respects this example code is very similar to a semaphore. If you really think that more than one process at a time is going to be updating the shared variables, then maybe a semaphore is the right choice for you. However we will control the update of the shared variables via critical sections, therefore this technique is just as safe as a true semaphore. What has more overhead, the ramp up cost of using CSemaphore all the time or the infrequent spin locking this approach might incur? The answer depends of what you are doing.
What makes a data segment shared

These three pragma statements override the default data segment behavior and creates a shared data segment. See MyClass.cpp in the DLL.

// Global and static member variables that are not shared.
...

#pragma data_seg("SHARED") // Begin the shared data segment.

// Define simple variables

// Integers, char[] arrays and pointers

// Do not define classes that require 'deep' copy constructors.
#pragma data_seg() // End the shared data segment and default back to
// the normal data segment behavior.


// This is the most important statement of all

// Ideally you can set this in the projects linker tab, but I never could get

// that to work. I stumbled across this in a discussion board response from

// Todd Jeffreys. This tells the linker to generate the shared data segment.

// It does not tell it what variables are shared, the other statements do that,

// but it does direct the linker to make provisions for the shared data segment.

#pragma comment(linker, "/section:SHARED,RWS")



That's it.
The code is written in VC 5. First build the DLL TestMemorySpace and then the driver executable Testexe.exe. Start two instances of the test exe, keep them both maximized, and click the button that says 'Read Me First'.




No comments: