Memory Mapping Helpers
Helper functions and a server/client pair for creating, opening, and mapping named shared memory backed by a file.
The four-step Win32 shared-memory recipe wrapped in small helpers. The server side creates the backing file (CreateMapFile), builds a named file-mapping object over it (CreateMap - the name is what lets another process find it), and views it into its address space (MapView). The client side just opens that same named object (OpenMap) and maps it; both processes then read and write the same bytes through ordinary pointers. Use this pattern when two of your own programs need to exchange data faster than pipes or sockets, or when you want scratch RAM persisted to a file.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**************************************************************************
* HANDLE CreateMapFile(char *MapFileName)
*
* Purpose: Create a Map file to map named share memory
*
* Inputs: none
*
* Returns: MapFileHandle - a handle to the file
* or NULL if failure
*
* Calls: CreateFile, ErrorOut
*
\**************************************************************************/
HANDLE CreateMapFile(char *MapFileName)
{
HANDLE MapFileHandle;
MapFileHandle= CreateFile(MapFileName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (MapFileHandle == INVALID_HANDLE_VALUE)
{
printf("CreateFile Error\n");
return(NULL);
}
else return(MapFileHandle);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**************************************************************************
* HANDLE CreateMap(HANDLE FileToBeMapped, char *MapName )
*
* Purpose: Create File Mapping object using the open file handle
*
* Inputs: FileToBeMapped - handle to the file
*
* Returns: MapHandle - handle to the file mapping object
* or NULL if failure
*
* Calls: CreateFileMapping, ErrorOut
\**************************************************************************/
HANDLE CreateMap(HANDLE FileToBeMapped, LPSTR MapName, DWORD MemorySize)
{
HANDLE MapHandle;
MapHandle = CreateFileMapping(FileToBeMapped, NULL, PAGE_READWRITE, 0, MemorySize, MapName);
if (MapHandle == NULL)
{
printf("CreateFileMapping Error\n");
return(NULL);
}
else return(MapHandle);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**************************************************************************
* LPVOID MapView(HANDLE hMap)
*
* Purpose: Map the file mapping object into address space
*
* Inputs: hMap - handle to the mapping object
*
* Returns: MappedPointer - pointer to the address space that the object is mapped into or NULL if failure
*
* Calls: MapViewOfFile, ErrorOut
*
\**************************************************************************/
LPVOID MapView(HANDLE hMap, DWORD SizeToMap)
{
LPVOID MappedPointer;
MappedPointer = MapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, SizeToMap);
if (MappedPointer == NULL)
{
printf("MapViewOfFile Error\n");
return(NULL);
}
else return(MappedPointer);
}
The client-side helper:
/*************************************************************************
* HANDLE OpenMap(LPSTR MapName)
*
* Purpose: Open the mapping object pointed to by MapName
*
* Inputs: none
*
* Returns: handle to mapped object or NULL if failure
*
* Calls: OpenFileMapping, ErrorOut
*
\*************************************************************************/
HANDLE OpenMap( LPSTR MapName)
{
HANDLE hAMap;
hAMap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, TRUE, MapName);
if (hAMap == NULL)
{
printf("OpenFileMapping error\n");
return NULL;
}
else return(hAMap);
}
And the server driver that ties the three steps together and writes a test string into the shared region:
#include <Windows.H>
#include <StdIO.H>
#include <StdLib.H>
#include "MemorySrvr.H"
#include "MemoryClnt.H"
#define MemoryFileName "C:\\Memory.Map"
#define MemoryMapName "MemMapping"
int main(void)
{
HANDLE MemoryFileHandle = NULL;
HANDLE MemoryMapHandle = NULL;
char *MappedMemory = NULL;
MemoryFileHandle = CreateMapFile(MemoryFileName);
MemoryMapHandle = CreateMap(MemoryFileHandle, MemoryMapName, 1024);
MappedMemory = (char *) MapView(MemoryMapHandle, 1024);
sprintf(MappedMemory, "%s/%d", "Hello: ", 12345);
printf("MappedMemory: %s\n", MappedMemory);
UnmapViewOfFile(MappedMemory);
return 0;
}
A client program simply calls OpenMap("MemMapping"), then MapView on the returned handle, and reads the same 1024 bytes.