Обмен через файлы, отображаемые на память
Изучение средств обмена данными между процессами мы начнем с файлов, отображенных на память. Этот способ обладает высоким быстродействием, так как данные передаются между процессами непосредственно через виртуальную память.
Методика работы с файлами, отображаемыми на память, была описана в первой главе. Эта методика может быть использована без изменений для организации передачи данных между процессами, однако мы все же сделаем некоторые замечания.
Напомним, что отображение создается функцией CreateFileMapping.
Вот фрагмент кода из приложения Oem2Char, в котором создается отображение файла, а затем выполняется отображение этого файла в память:
hFileMapping = CreateFileMapping(hSrcFile,
NULL, PAGE_READWRITE, 0, dwFileSize, NULL);
if(hFileMapping == NULL)
return;
lpFileMap = MapViewOfFile(hFileMapping,
FILE_MAP_WRITE, 0, 0, 0);
if(lpFileMap == 0)
return;
Здесь в качестве первого параметра для функции CreateFileMapping мы передаем идентификатор файла, открытого функцией CreateFile. Последний параметр указан как NULL, поэтому отображение не имеет имени.
Если отображение будет использоваться для передачи данных между процессами, удобно указать для него имя. Пользуясь этим именем, другие процессы смогут открыть отображение функцией OpenFileMapping.
Другое замечание касается идентификатора файла, передаваемого функции CreateFileMapping через первый параметр. Если вы создаете отображение только для того чтобы обеспечить передачу данных между процессами, вам не нужно создавать файл на диске компьютера. Указав в качестве идентификатора файла значение (HANDLE)0xFFFFFFFF, вы создадите отображение непосредственно в виртуальной памяти без использования дополнительного файла.
Ниже мы привели фрагмент кода, в котором создается отображение с именем $MyVerySpecialFileShareName$, причем это отображение создается в виртуальной памяти:
CHAR lpFileShareName[] =
"$MyVerySpecialFileShareName$";
hFileMapping = CreateFileMapping((HANDLE)0xFFFFFFFF,
NULL, PAGE_READWRITE, 0, 100, lpFileShareName);
После того как вы создали объект-отображение, следует выполнить отображение файла в память при помощи функции MapViewOfFile, как это было показано выше. В случае успеха эта функция вернет указатель на отображенную область памяти.
Итак, первый процесс создал отображение. Второй процесс, который будет выполнять обмен данными с первым процессом, должен открыть это отображение по имени при помощи функции OpenFileMapping, например, так:
hFileMapping = OpenFileMapping(
FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName);
Далее второе приложение выполняет отображение, вызывая функцию MapViewOfFile:
lpFileMap = MapViewOfFile(hFileMapping,
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
Пользуясь значением, полученным от функции MapViewOfFile, второе приложение получает указатель на отображенную область памяти. Физически эта область находится в тех же страницах виртуальной памяти, что и область, созданная первым процессом. Таким образом, два процесса получили указатели на общие страницы памяти.
Перед завершением своей работы процессы должны отменить отображение файла и освободить идентификатор созданного объекта-отображения:
UnmapViewOfFile(lpFileMap);
CloseHandle(hFileMapping);