# Sharing a dll's data with several processes ?

This topic is 3938 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hey, I would like to do something like: (pseudocode)
// In count.dll
int count;
int Acquire()
{
count++;
return count;
}

int Release()
{
count--;
return count;
}

// In the exec
int i = Acquire();
print(i);

/* Keep the exec running */
// ...

What I expect is that when I start my exec, it would print "1". Then I would start another "instance" of that exec and it would print "2". Is that possible at all ? As I understand dlls, they get loaded in the process adress space. Since 2 process (even running the same exe) would have different adress spaces, the dll would be loaded twice and each instance would not know of the other. Am I correct ? Thanks ! :)

##### Share on other sites
It's more like the DLL gets loaded once, and gets "mapped" into each process address space that uses it. However, each process gets its own copy of the DLL data area. Typically, you can't share data between DLLs. There is a way to accomplish this though, and it is by using a shared data segment via a #pragma. You do it like this:

#pragma data_seg(".MYSEGNAME")
static int count = 0;
#pragma data_seg()

Windows takes care of mapping this area into a shared memory segment between all processes that are using the DLL automatically. The name of your data segment must start with a period. This tells Windows that it should go into shared memory. Secondly, all variables in the segment must be static, and must be initialized. If either of these conditions is not met, you might have some big problems.

Hope this helps.

##### Share on other sites
Not every compiler will respect #pragma data_seg. Iirc, that's only available in MSVC.

With other compilers you'll have to use CreateFileMapping and MapViewOfFile. See Creating Named Shared Memory for an example of an approach to doing that.

##### Share on other sites
Great, thanks for the replies. I dont have to get this working on anything but MSVC for now.

##### Share on other sites
Quote:
 Original post by strtokYou do it like this:#pragma data_seg(".MYSEGNAME")static int count = 0;#pragma data_seg()Windows takes care of mapping this area into a shared memory segment between all processes that are using the DLL automatically. The name of your data segment must start with a period. This tells Windows that it should go into shared memory.

Where did you read that fact about beginning with a dot? I can't seem to find it anywhere. I'm a little dubious though, as all default PE section names begin with a dot and it is idiomatic to make your own segments do the same. If this had the poorly documented side-effect of mapping the page as shared then all hell would break loose.

The way I understand it is that you mark off your own data section as described above, and to mark it as shared you need to either use the following directive:

or perform the equivalent operation in the module definition file[1]:

SECTIONS

Anyway, the programmer should be sure that this is how they want to implement the inter-process communication before jumping straight in. Shared memory pages are notoriously troublesome with regard to deal-locks and race conditions. Far safer alternatives exist, such as Semaphores, Named Pipes and Memory-Mapped Files.

[1] Microsoft Knowledge Base

##### Share on other sites
If you need it portable, I recommend Boost Interprocess

It does what you need and alot of other cool stuff. In particular I make use of the interprocess message_queue class and it works very nicely.

##### Share on other sites
Well I understand that there are many safer approach but I'll explain what I'm doing and why I think that solution may be almost OK for me.

I just want my application not to be run twice. A few moments after trying the dll-thing, I just realized I did not need a dll at all, and I just did this:

// singleInstance.cpp#pragma data_seg(".MYAPP")static volatile bool bRunning = false;#pragma data_seg()#pragma comment(linker, "/section:.MYAPP,RWS")bool Initialize(){    if(bRunning)    {        /* error message */        return false;    }    bRunning = true;    return true;}

I have sucessfully used other methods with named OS objects (mutex for example) but I just wanted to see what other alternatives I had.

- My main concern is that the lock should be automatically removed in case of a crash. This is OK, unless I have failed to imagine some trickier situations.

- Another concern is that the check should be "atomical" in order to prevent 2 instances running exactly at he same time to both start sucessfully. This later point is not satisfied with the method I presented here, I think.

I don't need any kind of portability. At all [smile]
JA

##### Share on other sites
Quote:
 Where did you read that fact about beginning with a dot? I can't seem to find it anywhere. I'm a little dubious though, as all default PE section names begin with a dot and it is idiomatic to make your own segments do the same. If this had the poorly documented side-effect of mapping the page as shared then all hell would break loose.

I could have sworn that I read this somewhere, but upon double checking, I was also unable to find any evidence that this is necessary. My mistake!

Quote:
 The way I understand it is that you mark off your own data section as described above, and to mark it as shared you need to either use the following directive:

I've never used linker section sharing attributes before and never had any problems (I've been using this technique to share data between DLLs for years now). Perhaps it defaults to shareable? (EDIT: I went back and checked some of my old projects, and sure enough I was accomplishing this with a .def file. Oops, just one of those days I guess!)

For sharing complicated data, this is probably not the way to go. For sharing a few simple variables, it works fine with a little care.

[Edited by - strtok on May 15, 2007 4:02:48 PM]