Using shared memory under Windows. How to pass different data

16,350

Solution 1

Different processes have different address spaces. If you pass a valid pointer in one process to another process, it will probably point to random data in the second process. So you will have to copy all the data.

Solution 2

I strongly recommend you use Boost::interprocess. It has lots of goodies to manage this kind of stuff & even includes some special Windows-only functions in case you need to interoperate w/ other processes that use particular Win32 features.

The most important thing is to use offset pointers rather than regular pointers. Offset pointers are basically relative pointers (they store the difference between where the pointer is and where the thing pointed to is). This means that even if the two pointers are mapped to different address spaces, as long as the mappings are identical in structure then you are fine.

I've used all kinds of complicated data structures with offset smart pointers and it worked like a charm.

Solution 3

Shared Memory doesn't mean sending and receiving of Data. Its a memory created for number of processes without violation. For that you have to follow some mechanisms like locks so that the data will not corrupt.

In process 1 :

CreateFileMapping() : It will create the Shared Memory Block, with the name provided in last parameter, if it is not already present and returns back a handle (you may call it a pointer), if successful.

MapViewOfFile() : It maps (includes) this shared block in the process address space and returns a handle (again u can say a pointer).

With this pointer returned by MapViewOfFile() only you can access that shared block.

In process 2 :

OpenFileMapping() : If the shared memory block is successfully created by CreateFileMapping(), you can use it with the same name (name used to create the shared memory block).

UnmapViewOfFile() : It will unmap (you can remove the shared memory block from that process address space). When you are done using the shared memory (i.e. access, modification etc) call this function .

Closehandle() : finally to detach the shared memory block from process , call this with argument,handle returned by OpenFileMapping() or CreateFileMapping().

Though these functions look simple, the behaviour is tricky if the flags are not selected properly. If you wish to read or write shared memory, specify PAGE_EXECUTE_READWRITE in CreateFileMapping().

Whenever you wish to access shared memory after creating it successfully, use FILE_MAP_ALL_ACCESS in MapViewOfFile().

It is better to specify FALSE (do not inherit handle from parent process) in OpenFileMapping() as it will avoid confusion.

Solution 4

You CAN get shared memory to use the same address over 2 processes for Windows. It's achieveable with several techniques.

Using MapViewOfFileEx, here's the significant experpt from MSDN.

If a suggested mapping address is supplied, the file is mapped at the specified address (rounded down to the nearest 64K-boundary) if there is enough address space at the specified address. If there is not enough address space, the function fails.

Typically, the suggested address is used to specify that a file should be mapped at the same address in multiple processes. This requires the region of address space to be available in all involved processes. No other memory allocation can take place in the region that is used for mapping, including the use of the VirtualAlloc or VirtualAllocEx function to reserve memory.

If the lpBaseAddress parameter specifies a base offset, the function succeeds if the specified memory region is not already in use by the calling process. The system does not ensure that the same memory region is available for the memory mapped file in other 32-bit processes.

Another related technique is to use a DLL with a section marked Read + Write + Shared. In this case, the OS will pretty much do the MapViewOfFileEx call for you and for any other process which loads the DLL.

You may have to mark your DLL to a FIXED load address, not relocateable etc.. naturally.

Share:
16,350
asdrubael
Author by

asdrubael

Updated on June 13, 2022

Comments

  • asdrubael
    asdrubael almost 2 years

    I currently try to implement some interprocess communication using the Windows CreateFileMapping mechanism. I know that I need to create a file mapping object with CreateFileMapping first and then create a pointer to the actual data with MapViewOfFile. The example then puts data into the mapfile by using CopyMemory.

    In my application I have an image buffer (1 MB large) which I want to send to another process. So now I inquire a pointer to the image and then copy the whole image buffer into the mapfile. But I wonder if this is really necessary. Isn't it possible to just copy an actual pointer in the shared memory which points to the image buffer data? I tried a bit but didn't succeed.