Programming with Microsoft Visual C++.NET 6ed [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming with Microsoft Visual C++.NET 6ed [Electronic resources] - نسخه متنی

George Shepherd, David Kruglinski

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
توضیحات
افزودن یادداشت جدید








Memory-Mapped Files


In case you think you don't have enough memory management options already, I'll toss you another one. Suppose your program needs to read a device-independent bitmap (DIB) file. Your instinct might be to allocate a buffer of the correct size, open the file, and then call a read function to copy the whole disk file into the buffer. The Windows memory-mapped file is a more elegant tool for handling this problem, however. You simply map an address range directly to the file. When the process accesses a memory page, Windows allocates RAM and reads the data from disk.

Here's what the code looks like:

HANDLE hFile = ::CreateFile(strPathname, GENERIC_READ, 
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
ASSERT(hFile != NULL);
HANDLE hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY,
0, 0, NULL);
ASSERT(hMap != NULL);
LPVOID lpvFile = ::MapViewOfFile(hMap, FILE_MAP_READ,
0, 0, 0); // Map whole file
DWORD dwFileSize = ::GetFileSize(hFile, NULL); // useful info
// Use the file
::UnmapViewOfFile(lpvFile);
::CloseHandle(hMap);
::CloseHandle(hFile);

Here you're using virtual memory backed by the DIB file. Windows determines the file size, reserves a corresponding address range, and commits the file's storage as the physical storage for this range. In this case, lpvFile is the start address. The hMap variable contains the handle for the file-mapping object, which can be shared among processes if you want.

The DIB in the example above is a small file that you could read entirely into a buffer. Imagine a larger file for which you would normally issue seek commands. A memory-mapped file works for such a file as well because of the underlying virtual memory system. RAM is allocated and pages are read when you access them, and not before.





Note

By default, the entire file is committed when you map it, although it's possible to map only part of a file.


If two processes share a file mapping object (such as hMap in the sample code above), the file itself is, in effect, shared memory, but the virtual addresses returned by MapViewOfFile might be different. Indeed, this is the preferred Win32 method of sharing memory. (Calling the GlobalAlloc function with the GMEM_SHARE flag doesn't create shared memory as it did in Win16.) If memory sharing is all you want to do and you don't need a permanent disk file, you can omit the call to CreateFile and pass 0xFFFFFFFF as the CreateFileMapping hFile parameter. Now the shared memory will be backed by pages in the swap file. (See Programming Applications for Microsoft Windows, Fourth Edition by Jeffrey Richter for details on memory-mapped files.)





Note

If you intend to access only a few random pages of a file-mapping object that is backed by the swap file, you can use a technique that Jeffrey Richter describes in Programming Applications for Microsoft Windows. You call CreateFileMapping with a special flag, and then you commit specific address ranges later using the VirtualAlloc function.






Note

You might want to look carefully at the Windows message WM_COPYDATA. This message lets you transfer data between processes in shared memory without having to deal with the file mapping API. You must send this message rather than post it, which means that the sending process has to wait while the receiving process copies and processes the data.


Unfortunately, there's no direct support for memory-mapped files or shared memory in MFC. The CSharedFile class supports only clipboard memory transfers using HGLOBAL handles, so the class isn't as useful as its name implies.


/ 319