Specifying the Base Address of a Memory-Mapped File

[Previous] [Next]

Just as you can use the VirtualAlloc function to suggest an initial address to reserve address space, you can also use the MapViewOfFileEx function instead of the MapViewOfFile function to suggest that a file be mapped into a particular address.

 PVOID MapViewOfFileEx( HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap, PVOID pvBaseAddress); 

All the parameters and the return value for this function are identical to those of the MapViewOfFile function with the single exception of the last parameter, pvBaseAddress. In this parameter, you specify a target address for the file you're mapping. As with VirtualAlloc, the target address you specify should be on an allocation granularity boundary (64 KB); otherwise, MapViewOfFileEx returns NULL, indicating an error.

Under Windows 2000, specifying an address that is not a multiple of the allocation granularity causes the function to fail, and GetLastError will return 1132 (ERROR_MAPPED_ALIGNMENT). In Windows 98, the address will be rounded down to an allocation granularity boundary.

If the system can't map the file at this location (usually because the file is too large and would overlap another reserved address space), the function fails and returns NULL. MapViewOfFileEx does not attempt to locate another address space that can accommodate the file. Of course, you can specify NULL as the pvBaseAddress parameter, in which case MapViewOfFileEx behaves exactly the same as MapViewOfFile.

MapViewOfFileEx is useful when you're using memory-mapped files to share data with other processes. As an example, you might need a memory-mapped file at a particular address when two or more applications are sharing a group of data structures containing pointers to other data structures. A linked list is a perfect example. In a linked list, each node, or element, of the list contains the memory address of another element in the list. To walk the list, you must know the address of the first element and then reference the member of the element that contains the address of the next element. This can be a problem when you're using memory-mapped files.

If one process prepares the linked list in a memory-mapped file and then shares this file with another process, it is possible that the other process will map the file into a completely different location in its address space. When the second process attempts to walk the linked list, it looks at the first element of the list, retrieves the memory address of the next element, and then tries to reference this next element. However, the address of the next element in the first node will be incorrect for this second process.

You can solve this problem in two ways. First, the second process can simply call MapViewOfFileEx instead of MapViewOfFile when it maps the memory-mapped file containing the linked list into its own address space. Of course, this method requires that the second process know where the first process originally mapped the file when constructing the linked list. When the two applications have been designed to interact with each other—which is most likely the case—this isn't a problem: the address can be hard-coded into both, or one process can notify the other process using another form of interprocess communication, such as sending a message to a window.

The second method for solving the problem is for the process that creates the linked list to store in each node the offset from within the address space where the next node is located. This requires that the application add the offset to the base address of the memory-mapped file in order to access each node. This method is not great: it can be slow, it makes the program bigger (because of the additional code the compiler generates to perform all the calculations), and it can be quite error prone. However, it is certainly a viable method, and the Microsoft compiler offers assistance for based-pointers using the _ _based keyword.

Windows 98
When calling MapViewOfFileEx, you must specify an address that is between 0x80000000 and 0xBFFFFFFF, or MapViewOfFileEx will return NULL.

Windows 2000
When calling MapViewOfFileEx, you must specify an address that is in your process's user-mode partition, or MapViewOfFileEx will return NULL.



Programming Applications for Microsoft Windows
Programming Applications for Microsoft Windows (Microsoft Programming Series)
ISBN: 1572319968
EAN: 2147483647
Year: 1999
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net