views:

1753

answers:

5

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.

+4  A: 

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.

Zifre
Not always true.
RandomNickName42
@RandomNickName42: with the exception of shared memory, it is generally true for all common OSs.
Zifre
A: 

You can use Marshalling of pointers.

Vinay
+4  A: 

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.

Jason S
These are a.k.a. "based pointers", very much needed when 64-bit pointers are everywhere.
RandomNickName42
A: 

If it's possible, it would be best to have the image data loaded/generated directly into the shared memory area. This eliminates the memory copy and puts it directly where it needs to be. When it's ready you can signal the other process, giving it the offset into your shared memory where the data begins.

Rob K
+1  A: 

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.

RandomNickName42