Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

How to use a memory-mapped file with C# in WinCE

13 Dec 2013 0  
How to use a memory-mapped file with C# in WinCE.

Background

If we want to pass data between different process, we can use file, Windows Message Queue, or the network. But a memory-mapped file is the best technique.

Declare in .NET CF using C#:

public class WinCEConst
{
    public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
    public const UInt32 SECTION_QUERY = 0x0001;
    public const UInt32 SECTION_MAP_WRITE = 0x0002;
    public const UInt32 SECTION_MAP_READ = 0x0004;
    public const UInt32 SECTION_MAP_EXECUTE = 0x0008;
    public const UInt32 SECTION_EXTEND_SIZE = 0x0010;
    public const UInt32 SECTION_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED SECTION_QUERY
    SECTION_MAP_WRITE
    SECTION_MAP_READ
    SECTION_MAP_EXECUTE
    SECTION_EXTEND_SIZE);
    public const UInt32 FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS;
 
    public static IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
 
    public const int PAGE_READWRITE = 0x04;
    public const int PAGE_READONLY = 0x02;
    public const int FILE_MAP_READ = 0x0004;
    public const int FILE_MAP_WRITE = 0x0002;
}

public class WinCE
{
    // * WinCE use coredll.dll
    // * Windows use keneral32.dll
    [DllImport("iphlpapi.dll", CharSet = CharSet.Auto)]
    public static extern int GetAdaptersInfo(IntPtr pAdapterInfo, ref int pBufOutLen);
    [DllImport("Coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        uint dwShareMode,
        IntPtr lpSecurityAttributes,
        uint dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile
        );
    [DllImport("Coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr CreateFileMapping(
        IntPtr hFile,
        object lpFileMappingAttributes,
        uint flProtect,
        uint dwMaximumSizeHigh,
        uint dwMaximumSizeLow,
        string lpName);
    [DllImport("Coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr CreateFileForMapping(
        string lpFileName,
        uint dwDesiredAccess,
        uint dwShareMode,
        IntPtr lpSecurityAttributes, // set null
        uint dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile);
    public static IntPtr OpenFileMapping(uint dwDesiredAccess, bool bInheritHandle, string lpName)
    {
        IntPtr t_pHandle = CreateFileMapping(new IntPtr(-1), null,
                WinCEConst.PAGE_READWRITE, 0, 0, lpName);
        return t_pHandle;
    }
    [DllImport("Coredll.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CloseHandle(IntPtr hObject);
    [DllImport("Coredll.dll", SetLastError = true)]
    public static extern IntPtr MapViewOfFile(
        IntPtr hFileMappingObject,
        uint dwDesiredAccess,
        uint dwFileOffsetHigh,
        uint dwFileOffsetLow,
        uint dwNumberOfBytesToMap);
    [DllImport("Coredll.dll", SetLastError = true)]
    public static extern bool UnmapViewOfFile(IntPtr lpBaseAddress);
}

How to create a memory-mapped file and put data to it

const string MapName = "OrzCloud";
const int MapSize = 1024;
IntPtr m_pMapFile;
IntPtr m_pBuff;
string data = "TestTest";
 
// create map file
m_pMapFile = WinCE.CreateFileMapping(
  WinCEConst.INVALID_HANDLE_VALUE, null,WinCEConst.PAGE_READWRITE, 0, MapSize, MapName);
t_i4Error = Marshal.GetLastWin32Error();
 
// get map file
m_pBuff = WinCE.MapViewOfFile(m_pMapFile,WinCEConst.FILE_MAP_ALL_ACCESS, 0, 0, MapSize);
t_i4Error = Marshal.GetLastWin32Error();
// String to byte array
byte[] t_bData = Encoding.ASCII.GetBytes(data);
// write data to map file
Marshal.Copy(t_bData, 0, m_pBuff, t_bData.Length);

How to open an existing memory-mapped file and get data

m_pMapFile = WinCE.OpenFileMapping(WinCEConst.FILE_MAP_ALL_ACCESS, false, MapName);
// check error code
t_i4Error = Marshal.GetLastWin32Error();

// get map file
m_pBuff = WinCE.MapViewOfFile(m_pMapFile, WinCEConst.FILE_MAP_ALL_ACCESS, 0, 0, MapSize);
 
byte[] bytData = new byte[MapSize];
// read data from map file
Marshal.Copy(m_pBuff, bytData, 0, MapSize);
// change byte array to string
string data = Encoding.ASCII.GetString(bytData,0,MapSize).Trim();

How to close a memory-mapped file

WinCE.UnmapViewOfFile(m_pBuff);
WinCE.CloseHandle(m_pMapFile);

References

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here