Thread: Memory Mapped File

  1. #1
    Registered User
    Join Date
    Feb 2008
    Posts
    14

    Memory Mapped File

    Hi,

    I'm working on an assignment in which I have to use a memory mapped file.

    In another assignment I've done this before like this:

    Code:
    static unsigned long *Buff = NULL;
    static HANDLE hFileMap;
    
         // Create File Mapping
         hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, maxSize + 1, "memMappedFile");
         if (!hFileMap)
         {
            perror("Unable to create file mapping,Error");
            return;
         }
         
         // Map View Of File (access memory mapped file and place it in memory)
         if ( !(Buff = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0) ) )
         {
            perror("Unable to create view of mapped file,Error");
            
            // Cleanup
            CloseHandle(hFileMap);
            
            return;
         }
    I've used the code above to create a circulair buffer in C.

    I'm, however, using using C++ now and the above code (when modified) fails.

    I want to map an arraylist:

    string neighbourList[5][7]

    ...to make it available for another proces.

    Can someone help me out here?

    I'm not sure if I can map a two dimensional array at all, but I'm receiving the following error:

    error C2440: '=' : cannot convert from 'LPVOID' to 'std::string [5][7]'
    Last edited by kevinv2u; 03-26-2008 at 06:48 AM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    But the memory held by an object is not (guaranteed to be) a contiguous chunk of memory. So the string is perhaps a structure like this:
    Code:
    class string {
       char *strdata;
       int len;
    };
    So whilst you can solve the problem of storing a "string array" in the buffer by using (void *) to make it a compatible pointer, you are not storing the string content in the file.

    You probably need to rethink this strategy.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Don't try to host any std:: objects in shared memory - there's too many things that can and will go wrong. Stick with built-in data types or simple structures composed of built-in types.

    gg

  4. #4
    Registered User
    Join Date
    Feb 2008
    Posts
    14
    See last message...
    Last edited by kevinv2u; 03-26-2008 at 09:59 AM.

  5. #5
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    to copy C-strings use strcpy
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Besided Vart's comment, are you sure this is right:
    Code:
    MapViewOfFile(hNeighbourListMemMap, FILE_MAP_WRITE, 5, 5, 0)
    
    // This is how MSDN describes the function:
    LPVOID WINAPI MapViewOfFile(
      __in  HANDLE hFileMappingObject,    hNeighbourListMemMap   OK
      __in  DWORD dwDesiredAccess,        FILE_MAP_WRITE   OK
      __in  DWORD dwFileOffsetHigh,         5 * 4GB                  ???
      __in  DWORD dwFileOffsetLow,          + 5 bytes.         
      __in  SIZE_T dwNumberOfBytesToMap   0                        OK
    );
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Feb 2008
    Posts
    14
    I've got a bit of a mess right now...sorry for that!

    Code:
    	static HANDLE hFileMap;
    	static unsigned long *Buff = NULL;
    
         // Create File Mapping (use invalid handle, don't link to real file, +1 for synchronization)
         hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 100, "memMappedFile");
         if (!hFileMap)
         {
            perror("Unable to create file mapping,Error");
            return;
         }
         
         // Map View Of File (access memory mapped file and place it in memory)
         if ( !(Buff = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0) ) )
         {
            perror("Unable to create view of mapped file,Error");
            
            // Cleanup
            CloseHandle(hFileMap);
            
            return;
         }
    
    	 Buff[0] = 100;
    Can someone tell me how the VOID thing works in C++.
    I'm getting the following error:

    "error C2440: '=' : cannot convert from 'LPVOID' to 'unsigned long *'"

    I need to experiment a bit more with MMF after I get this working to ask a proper question.
    Last edited by kevinv2u; 03-26-2008 at 10:05 AM.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    MapViewOfFile returns void*, but Buff is unsigned long*.
    C++ requires an explicit cast to compile this (because you have two different pointer types).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    Registered User
    Join Date
    Feb 2008
    Posts
    14
    Ok, that works! Thanks!

    If anyone can use it, here is the code:

    Code:
    	static HANDLE hFileMap;
    	static char *Buff = NULL;
    
        // Create File Mapping (use invalid handle, don't link to real file, +1 for synchronization)
        hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 100, "memMappedFile");
        if (!hFileMap)
        {
    		perror("Unable to create file mapping,Error");
    		return;
        }
        
    	Buff = static_cast<char*> ( MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0) );
    	
    	Buff[0] = 'H'; // uncomment for client,
    	Buff[1] = 'i';  // to read from buffer
    
    	cout << "Buff0 = " << Buff[0] << ", Buff1=" << Buff[1] << ".\n";
    The next step is create a char array...

  10. #10
    Registered User
    Join Date
    Feb 2008
    Posts
    14
    I've got the following code so far for a char array:

    Code:
    	static HANDLE hFileMap;
    	static char *Buff[2];
    
        // Create File Mapping (use invalid handle, don't link to real file, +1 for synchronization)
        hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 100, "memMappedFile");
        if (!hFileMap)
        {
    		perror("Unable to create file mapping,Error");
    		return;
        }
        
    	*Buff = static_cast<char*> ( MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0) );
    	
    	char *test;
    	test = "hello";
    
    	Buff[0] = "hello";
    	Buff[1] = "world";
    
    	cout << "Buff0 = " << Buff[0] << ", Buff1 = " << Buff[1] << ".\n";
    ...The client does not read anything from the buffer.

    If I use
    Code:
    strcpy(*Buff, test);
    ...and then read from Buff[0] it works.

    But I cannot assign anything to Buff[1]...

    Can anyone point me in the right direction? Or am I doing something completely wrong here?

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    What are you doing with multiple pointers? You need only one pointer to the memory area.
    Therefore
    Code:
    static char *Buff[2];
    Should be
    Code:
    static char* Buff;
    And once more - do not do this:
    Code:
    Buff[0] = "hello";
    Buff[1] = "world";
    You are putting pointers in the shared memory. Pointers which will be invalid in the other process.
    Therefore you must use strcpy to copy the string into the shared memory.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Registered User
    Join Date
    Feb 2008
    Posts
    14
    Ok, I've changed my code.

    Now, when I use:
    Code:
    	char *test;
    	test = "hello";
    
    	strcpy(Buff, test);
    ...It assigns the string, but is there a way to read the string like this:

    Buff[0] returns "hello"
    Buff[1] returns "world"

    When I use Buff[0] it returns the first character and so on.

    Also, I can only use one string in Buff, if I use strcpy a second time, it overwrites the first string, whereas by using Buff[0] = "hello" and Buff[1] = "world" I can have multiple strings.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You really have no grasp of C-style strings.
    So... here you go. Read up.
    http://www.cprogramming.com/tutorial/c/lesson9.html

    And this:
    Code:
    	char *test;
    	test = "hello";
    
    	strcpy(Buff, test);
    Is the same as
    Code:
    	strcpy(Buff, "hello");
    And a C-style string is basically an array of chars. So perhaps read a little about arrays, too.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Registered User
    Join Date
    Feb 2008
    Posts
    14
    I know that both code is the same, and I also know that a string is actually an array of characters.

    What I meant was that I want to assign a pointer char array, so I can have some sort of string array to assign multiple string values to the buffer with use of the index like this:

    Buff[0] = "hello"
    Buff[1] = "world"

    I know I can just put all strings behind each other with \0 too, but I like the above method and want to use that in my 'client' too...

    Aaah, I'll guess I will have to read some more about C tough.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Don't do it. It will never work to assign like that.
    strcpy and strcat are your friends. Just as long as you treat the shared memory as char*.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 02-06-2009, 12:27 PM
  2. gcc link external library
    By spank in forum C Programming
    Replies: 6
    Last Post: 08-08-2007, 03:44 PM
  3. Inventory records
    By jsbeckton in forum C Programming
    Replies: 23
    Last Post: 06-28-2007, 04:14 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM