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

CMemMapFile v1.41

0.00/5 (No votes)
3 Mar 2000 1  
A freeware MFC class to encapsulate Memory Mapped Files.
  • Download source files - 17 Kb
  • Introduction

    Welcome to CMemMapFile, A freeware MFC class to encapsulate memory mapped files.


    Features
    History
    CMemMapFile class members
    Usage
    Contacting the Author


    Features

    Memory mapping is a powerful mechanism Win32 provides to implement shared memory and also to access files though a simple memory pointer without having to implement your own home brewed buffering mechanisms. As an example its as simple as calling:
    void* lpData = mmf.Open();
    CharUpperBuff((char*) lpData, mmf.GetLength());
    

    to convert a file (of any length) to upper case.

    Areas where you might find this of interest include very large database files with fixed records, audio processing, string operations and image processing.

    The other side of memory mapped files is to implement shared memory. As you will probably know, Win32 puts each process into its own address space, thus making it impossible to pass ordinary pointers across process boundaries. With memory mapped files you get back this very useful mechanism.

    The source zip file contains the CMemMapFile source code and a simple dialog based application which demonstrates all the functionality of the class. For further details about the example program have a look at the BOOL CTestmemmapApp::InitInstance() function and the CDialog1 member functions both in testmemmap.cpp.


    History

    V1.0 (31 March 1998)
    • Class now avoids trying to lock the mutex if only read access is required.
    • User now has the option of specifying whether a file should be mapped with a NULL terminator at the end. Can prove helpful when you want to use some of the C runtime functions on the pointer returned.

    V1.1 (20 April 1998)

    • Now uses GetFileSize() SDK call instead of GetFileInformationByHandle() as a more "reliable" way to determine file length.
    • Included TRACE statements to call GetLastError() in all places where SDK functions fail.

    V1.2 (29 May 1998)

    • Mapping a file now has the option of making it named or not.

    V1.3 (22 October 1998)

    • Fixed a bug in a number of calls to CreateMappingName() when the classes were being used to share memory.
    • New documentation in the form of a HTML file.
    • Sample now ships as standard with VC 5 workspace files.
    • Tidy up of the demo app including:
      • Made the amount of text being shared a constant of MAX_EDIT_TEXT instead of hardcoding it to 20 everywhere in the sample.
      • Changed where the timer is being created to OnInitDialog().
      • Tidied up the initialisation sequence in OnInitDialog().
      • Now using _tcscpy() instead of _tcsncpy() to ensure array is null terminated.
      • Fixed resource.h which was causing the resources to fail to compile.
      • Removed unnecessary symbols from resource.h.
      • Optimized the way the OnTimer() code works to only update the text when it has changed in the MMF. This means that you can type continuously into the edit control.

    V1.4 (30 March 1999)

    • Minor updates to the style of the help file.
    • Code is now UNICODE compliant and build configurations are provided.
    • Code now supports growable memory mapped files as provided with Windows 2000 and NTFS 5 volumes.
    • Addition of accessor functions for file handle and file mapping handle.

    V1.41 (21 April 1999)

    • Added code to work around a Windows bug where you try to memory map a zero length file on Windows 95 or 98.


    CMemMapFile Class Members

    CMemMapFile
    ~CMemMapFile
    MapFile
    MapMemory
    MapExistingMemory
    Open
    Close
    UnMap
    IsOpen
    GetLength
    Flush
    GetMappingName
    GetFileHandle
    GetFileMappingHandle


    CMemMapFile::CMemMapFile

    CMemMapFile();

    Remarks:
    Standard Constructor for the class.


    CMemMapFile::~CMemMapFile

    ~CMemMapFile();

    Remarks:
    Standard Destructor for the class. Calls the UnMap() function.


    CMemMapFile::MapFile

    BOOL MapFile(const CString& sFilename, BOOL bReadOnly = FALSE, DWORD dwShareMode = 0, BOOL bAppendNull = FALSE, BOOL bNamed = FALSE, BOOL bGrowable = FALSE);

    Return Value:
    TRUE if the file was successfully mapped otherwise FALSE.

    Parameters:

    • sFilename -- The filename to memory map.
    • bReadOnly -- Set to true if you are not interested in modifying the file.
    • dwShareMode -- The share flags to use when calling CreateFile(). This may be prove useful if you want to map a file using MMF techniques but allow other processes access to it as read only.
    • bAppendNULL -- Set to TRUE and it will add a double null to the end of the file mapping. This may prove useful if you want to treat the data as a null terminated ASCII or Unicode character array.
    • bNamed -- Determines whether or not you want to make the memory mapped files named. Normally when you map a file there is no need to do this as the MMF is not being used to share memory.
    • bGrowable -- If you set this value to TRUE, then the underlying file will be set to be a "sparse" file. In the context of memory mapped files, this means that you will not get access violations when you try to write past the end of the file, instead the OS will silently grow the file for you. Please note that this is only supported on NTFS 5 volumes on Windows 2000 aka NT 5. This could be useful where you want to use memory mapped files to implement features such as direct to disk audio recording where you do not want to preallocate a certain size disk file up front. Please see the MSDN or Platform SDK for further information on this new feature in Windows 2000.

    Remarks:
    Maps a file system file. Note that an attempt to modify a file mapping when it is in read only mode will generate an access violation.


    CMemMapFile::MapMemory

    BOOL MapMemory(const CString& sName, DWORD dwBytes, BOOL bReadOnly = FALSE);

    Return Value:
    TRUE if the memory was successfully mapped otherwise FALSE.

    Parameters:

    • sName -- The name to use.
    • dwBytes -- The size to map.
    • bReadOnly -- Same usage as in MapFile().

    Remarks:
    This creates a piece of shared memory.


    CMemMapFile::MapExistingMemory

    BOOL MapMemory(const CString& sName, DWORD dwBytes, BOOL bReadOnly = FALSE);

    Return Value:
    TRUE if the memory was successfully mapped otherwise FALSE.

    Parameters:

    • sName -- The name to use.
    • dwBytes -- The size to map.
    • bReadOnly -- Same usage as in MapFile().

    Remarks:
    This function is quite similar to MapMemory() except that it fails it the mapping is already created. This function can be used to connect to existing shared memory or where you want to detect if this is the first instance of your program to run.


    CMemMapFile::Open

    LPVOID Open(DWORD dwTimeout = INFINITE);

    Return Value:
    Pointer to the data as stored in the memory mapped file.

    Parameters:

    • dwTimeout -- The time in milliseconds to wait if the mapping is already opened by another thread or process.

    Remarks:
    Once you have called MapFile(), MapMemory() or MapExisitingMemory() you can call this function to actually get a pointer to the data. Internally the class uses a mutex to synchronise access to the memory so that you do not have to worry about thread synchronisation problems when using the class. If you use the default value then your thread will be suspended indefinitely if another thread is using the object.


    CMemMapFile::Close

    BOOL Close();

    Remarks:
    This is the corollary of the Open() function and there should be a matching call to Close for each call to Open. After calling close you are free to call Open again to get back the pointer.


    CMemMapFile::UnMap

    void UnMap();

    Remarks:
    This unmaps the object and releases all the file handles and synchronisation objects. You can consider this function to be the corollary to the Map...() functions. This function is also called in the destructor if you forget to do it yourself.


    CMemMapFile::IsOpen

    BOOL IsOpen() const;

    Return Value:
    TRUE if this object is already open otherwise FALSE.


    CMemMapFile::GetLength

    DWORD GetLength() const;

    Return Value:
    The length of the mapping object. This is the maximum offset in bytes which you can index into the mapping pointer. Overshooting this boundary will generate an access violation. If you have mapped a file, then this will correspond to the file size.


    CMemMapFile::Flush

    BOOL Flush();

    Return Value:
    TRUE if the flush was successful otherwise FALSE.

    Remarks:
    Flushes the mapping object to disk.


    CMemMapFile::GetMappingName

    CString GetMappingName() const;

    Return Value:
    The name as a CString which this object is known to the OS as.


    CMemMapFile::GetFileHandle

    HANDLE GetFileHandle() const;

    Return Value:
    The file handle which this memory mapping instance encapsulates. This value returned will be INVALID_HANDLE_VALUE if it is called on a memory mapping which is being used to share memory rather than a file on the file system.


    CMemMapFile::GetFileMappingHandle

    HANDLE GetFileMappingHandle() const;

    Return Value:
    The file mapping handle which this memory mapping instance encapsulates.



    Usage

    Included is a simple dialog based application which demonstrates the 2 main features of memory mapped files, namely mapping a file system file to a pointer and implementation of shared memory. For further details about the example program have a look at the CTestmemmapApp::InitInstance() function and the CDialog1() member functions both in testmemmap.cpp.

    To use CMemMapFile in your project simply include memmap.cpp from the test application in your application and #include "memmap.h" in whichever files you want to use the class in.


    Contacting the Author

    PJ Naughter
    Email: pjn@indigo..ie
    Web: http://www.naughter.com
    21st April 1999


    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