// In count.dll
int count;
int Acquire()
{
count++;
return count;
}
int Release()
{
count--;
return count;
}
// In the exec
Load(count.dll);
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 ! :)
Sharing a dll's data with several processes ?
Hey, I would like to do something like: (pseudocode)
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.
#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.
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.
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.
Quote:Original post by strtok
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.
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:
#pragma comment(linker, "/section:.MYSEGNAME,RWS")
or perform the equivalent operation in the module definition file[1]:
SECTIONS
.shared READ WRITE SHARED
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
Admiral
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.
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.
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:
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
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
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]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement