Skip to content

Instantly share code, notes, and snippets.

@jsok
Created June 27, 2012 01:56
Show Gist options
  • Save jsok/3000825 to your computer and use it in GitHub Desktop.
Save jsok/3000825 to your computer and use it in GitHub Desktop.
Shared memory on Windows Platform SDK
Example of how to use Windows Platform SDK shared memory functions between C and C#.
Code borrowed from:
http://www.albahari.com/nutshell/ch22.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366551(v=vs.85).aspx
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
#define BUF_SIZE 256
TCHAR szName[]=TEXT("jonathans_shmem");
int main(int argc, char *argv[])
{
HANDLE hMapFile;
char *pBuf, *tmp;
int i, len;
printf("Started client...\n");
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
szName); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not open file mapping object (%d).\n"),
GetLastError());
return 1;
}
pBuf = (char *) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
CloseHandle(hMapFile);
return 1;
}
tmp = pBuf;
len = (int) *((int *)tmp);
tmp += sizeof(int);
for (i = 0; i < len; i++)
printf("%c", tmp[i]);
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
getc(stdin);
return 0;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace dotnet_client
{
class Program
{
static void Main(string[] args)
{
SharedMem shmem = new SharedMem("jonathans_shmem", false, 256);
ASCIIEncoding ascii = new ASCIIEncoding();
byte[] message = ascii.GetBytes("Hello World!");
Int32 len = message.Length;
Int32[] len_copy = { len };
Marshal.Copy(len_copy, 0, shmem.Root, 1);
Marshal.Copy(message, 0, shmem.Root+Marshal.SizeOf(len), message.Length);
Console.ReadLine();
}
}
}
public class SharedMem : IDisposable
{
// Here we're using enums because they're safer than constants
enum FileProtection : uint // constants from winnt.h
{
ReadOnly = 2,
ReadWrite = 4
}
enum FileRights : uint // constants from WinBASE.h
{
Read = 4,
Write = 2,
ReadWrite = Read + Write
}
static readonly IntPtr NoFileHandle = new IntPtr(-1);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFileMapping(IntPtr hFile,
int lpAttributes,
FileProtection flProtect,
uint dwMaximumSizeHigh,
uint dwMaximumSizeLow,
string lpName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr OpenFileMapping(FileRights dwDesiredAccess,
bool bInheritHandle,
string lpName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr MapViewOfFile(IntPtr hFileMappingObject,
FileRights dwDesiredAccess,
uint dwFileOffsetHigh,
uint dwFileOffsetLow,
uint dwNumberOfBytesToMap);
[DllImport("Kernel32.dll")]
static extern bool UnmapViewOfFile(IntPtr map);
[DllImport("kernel32.dll")]
static extern int CloseHandle(IntPtr hObject);
IntPtr fileHandle, fileMap;
public IntPtr Root { get { return fileMap; } }
public SharedMem(string name, bool existing, uint sizeInBytes)
{
if (existing)
fileHandle = OpenFileMapping(FileRights.ReadWrite, false, name);
else
{
fileHandle = CreateFileMapping(NoFileHandle,
0,
FileProtection.ReadWrite,
0,
sizeInBytes,
name);
}
if (fileHandle == IntPtr.Zero)
throw new Exception
("Open/create error: " + Marshal.GetLastWin32Error());
// Obtain a read/write map for the entire file
fileMap = MapViewOfFile(fileHandle, FileRights.ReadWrite, 0, 0, 0);
if (fileMap == IntPtr.Zero)
throw new Exception
("MapViewOfFile error: " + Marshal.GetLastWin32Error());
}
public void Dispose()
{
if (fileMap != IntPtr.Zero) UnmapViewOfFile(fileMap);
if (fileHandle != IntPtr.Zero) CloseHandle(fileHandle);
fileMap = fileHandle = IntPtr.Zero;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment