Archived

This topic is now archived and is closed to further replies.

steg

sharing memory across processes

Recommended Posts

steg    390
Hi all, I want to be able to share the same memory from a DLL to other processes, is this possible? For example, the DLL may have some memory in it that is a message stack for example, now process A requests this stack and another process B also requests it, how can they get the same memory where this stack is stored ? Any help is VERY much appreciated. Steve

Share this post


Link to post
Share on other sites
Oluseyi    2112
Best bet for a DLL is to wrap the memory, statically declared, in a function:
char * GetSharedMemHandle( void )
{
static char * mem = new char[ 1024 ];
return mem;
}

Problem is this doesn''t ensure exclusive access at any given point; you''ll require either a mutex or a semaphore for that. To implement that infers some sort of continuous operation/monitoring, which is not so easily done with a function (understatement of the decade), thus necessitating the construction of a thread to manage the memory:

void Mem_ThreadProc( void * args )
{
// whatever
}
 
HANDLE GetSharedMemHandle( void )
{
static HANDLE hThread = CreateThread( ..., Mem_ThreadProc, args, ... ); // fill in parameters
return hThread;
}

Now you can access and manipulate the memory by sending messages to the thread queue of Mem_ThreadProc (remember to set up the message queue in the function).

Quite an inelegant solution, but that wasn''t the purpose for which dynamic libraries were created. Perhaps if you said what you were trying to acheive a better solution could be suggested.

Share this post


Link to post
Share on other sites
steg    390
Thanks,

I have a DLL which has a message stack, similar to the following:

struct messages {
UINT uiMsgId;
BOOL bProcessed;
UINT uiRetVal;
--
--
messages *next;
};

Now process A loads this DLL up and requests this message stack, process B also does this, I want them to get the same message stack(same memory). Thus if, the first message had a uiMsgId of 0x2, both process A and B would see this. Am I making sense ?
Basically, share this memory across multiple processes.

I''ve heard you could use maybe memory mapped files ?

Kind regards,
Steve

Share this post


Link to post
Share on other sites
S1CA    1418
The problem of course is that only one process is running at any one time, and so only one virtual address space is mapped in (so two processes can use the same addresses for totally different things - if you find and display the address of WinMain for multiple processes you''ll notice that the address is usually the same).


For large amounts and/or dynamicly allocated memory, then memory mapped files are indeed the best way IMO (take a look at CreateFileMapping, MapViewOfFile etc - IIRC there''s a sample in MSDN showing use too). Memory mapped files are actually central to the way Windows handles paging out virtual memory so the performance is good.

An alternative for medium amounts is to use things like named pipes.


Finally for small amounts of statically allocated memory that you need to share between processes you can do:

#pragma data_seg(".shsec")
volatile MyDataStructure g_mySharedData;
#pragma data_seg()
#pragma comment(linker,"/SECTION:.shsec,RWS")


That creates a new data section in the final executable called ".shsec" which will contain only g_mySharedData.

g_mySharedData is marked as volatile to prevent the compiler optimising the use of that structure (i.e. you''re telling the compiler "something outside of this process/code might need to modify this so don''t reorganise, inline etc).

The closing data_seg() ends the PE section.

Finally the comment(linker... sets a new linker option. The option being set is /SECTION which controls the attributes for a PE section. RWS means: Readable, Writable and Shared. (i.e. you can read and write the data without an access violation and it''s shared between processes).

There are other /SECTION: options, but for most things you won''t want to use them.

Be warned, the above shares DATA, not code or the program stack, so for example:

class Blah
{
public:
int summat();
}

int Blah::summat()
{
static int nCount = 0;
return ++nCount;
}


The nCount would not be shared across instances. You''d likely run into even more problems if you tried to share a class with a vtable (i.e. virtual members) - so don''t do it, share DATA...

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
steg    390
Thanks Simon,

I have implemented it using memory mapped files, now the problem is, I cannot grow the area of memory that is shared :-(

For example, the structure below is set up as shared memory, but I could have more of these structures stored in a link list for example.

struct MessageStack {
char lpMsg[20];
UINT m_uiMessageID;
BOOL m_bProcessed;
MessageStack *pNext;
}*msg;

When a process accesses this memory area, the Message process application would need to add a new one, I don''t know a way of doing this and keeping it shared ?

Kind regards,
Steve

PS - Simon, liked the idea of accessing Internet Explorer via it''s com interface in my other thread on activeX controls, problem is, the browser may not be just Internet Explorer, could be on a linux box for instance in Mozilla ?


Share this post


Link to post
Share on other sites
S1CA    1418
You probably know the "maximum" you''ll ever use though (the address space is at worst 2GB) -:

use SEC_RESERVE when you create the mapping to reserve (**but not commit**) say 4Mb of the address space (or whatever your maximum is). That doesn''t use any memory or disk space.

when you need to grow your data structures, use VirtualAlloc() to commit storage to to the part of the address range. Bear in mind that "commit" just means "commit some storage _somewhere_", it doesn''t necessarily mean physical RAM, the result of your VirtualAlloc() is likely to be the file mapping file growing in size by the alloc''d amount.

Even if you don''t use VirtualAlloc() you can change the map view (MapViewOfFile) without disturbing the actual contents of the mapping object (i.e. the temporary page file being used as virtual memory for the shared range)


-------
On the ActiveX issue I''m not sure exactly what you want (can you even have an ActiveX control on a Linux machine...?)
- AFAIK all properly Windows compatible browsers (Netscape, IE etc) will support certain COM interfaces to their browsing capabilities.

However if a control is loaded into an application, then THAT application OWNS the control - and since that application also provides the UI for it, I don''t see any valid reason why the application would expose a nice programming interface to it.

I see it as me working on a game and having an internal class called MyHardwareJoystickHandler - I wouldn''t make a public export for that, even for a moddable game because I don''t see any problems that would be solved by me doing that. I suspect access to someone elses ActiveX control in an app that doesn''t support OLE (I think at least IE and Netscape do) is thought of in the same way.

If you want to use the control, make your own container.

What are you trying to do? - stop pop-ups?, spoof input to a Flash control? display a browser window from your app and control what happens?

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

Share this post


Link to post
Share on other sites
steg    390
Thanks again Simon,

I''ve actually used a static list now for the message stack stuff, works quite well.

As for the ax control, well, the control I wrote myself, it is for work, it displays graphical information for diagnostics on a certain model of car. The communication DLL at the moment speaks to my control via windows messages, was wanting to make this a little cleaner and have the DLL directly call methods within my control instead. The communication DLL is again, one we have wrote ourselves, it sends such messages as simple ones for example, update a progress bar, enable/disable certain buttons in the ax control etc.
Ax controls can be run on linux, there are plugins on netscape and mozilla. Still, linux doesn''t support COM, it has its own way of doing this of which I guess you are aware of, COBRA for example.

I really appreciate the time you have given to my questions, thanks Simon.

Regards,
Steve

Share this post


Link to post
Share on other sites