Приложение Fmap/Client
Исходные тексты приложения Fmap/Client, предназначенного для совместной работы с приложением Fmap/Server, представлены в листинге2.2.
Листинг 2.2. Файл fmap/client/client.c
#include <windows.h>
#include <stdio.h>
#include <conio.h>
// Идентификаторы объектов-событий, которые используются
// для синхронизации задач, принадлежащих разным процессам
HANDLE hEvent;
HANDLE hEventTermination;
// Имя объекта-события для синхронизации ввода и отображения
CHAR lpEventName[] =
"$MyVerySpecialEventName$";
// Имя объекта-события для завершения процесса
CHAR lpEventTerminationName[] =
"$MyVerySpecialEventTerminationName$";
// Имя отображния файла на память
CHAR lpFileShareName[] =
"$MyVerySpecialFileShareName$";
// Идентификатор отображения файла на память
HANDLE hFileMapping;
// Указатель на отображенную область памяти
LPVOID lpFileMap;
int main()
{
CHAR chr;
printf("Mapped and shared file, client process\n"
"(C) A. Frolov, 1996, Email: frolov@glas.apc.org\n"
"\n\nPress <ESC> to terminate...\n");
// Открываем объект-событие для синхронизации
// ввода и отображения
hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, lpEventName);
if(hEvent == NULL)
{
fprintf(stdout,"OpenEvent: Error %ld\n",
GetLastError());
getch();
return 0;
}
// Открываем объект-событие для сигнализации о
// завершении процесса ввода
hEventTermination = OpenEvent(EVENT_ALL_ACCESS,
FALSE, lpEventTerminationName);
if(hEventTermination == NULL)
{
fprintf(stdout,"OpenEvent (Termination): Error %ld\n",
GetLastError());
getch();
return 0;
}
// Открываем объект-отображение
hFileMapping = OpenFileMapping(
FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName);
// Если открыть не удалось, выводим код ошибки
if(hFileMapping == NULL)
{
fprintf(stdout,"OpenFileMapping: Error %ld\n",
GetLastError());
getch();
return 0;
}
// Выполняем отображение файла на память.
// В переменную lpFileMap будет записан указатель на
// отображаемую область памяти
lpFileMap = MapViewOfFile(hFileMapping,
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
// Если выполнить отображение не удалось,
// выводим код ошибки
if(lpFileMap == 0)
{
fprintf(stdout,"MapViewOfFile: Error %ld\n",
GetLastError());
getch();
return 0;
}
// Цикл ввода. Этот цикл завершает свою работу,
// когда пользователь нажимает клавишу <ESC>,
// имеющую код 27
while(TRUE)
{
// Проверяем код введенной клавиши
chr = getche();
// Если нажали клавишу <ESC>, прерываем цикл
if(chr == 27)
break;
// Записываем символ в отображенную память,
// доступную серверному процессу
*((LPSTR)lpFileMap) = chr;
// Устанавливаем объект-событие в отмеченное
// состояние
SetEvent(hEvent);
}
// После завершения цикла переключаем оба события
// в отмеченное состояние для отмены ожидания в
// процессе отображения и для завершения этого процесса
SetEvent(hEvent);
SetEvent(hEventTermination);
// Закрываем идентификаторы объектов-событий
CloseHandle(hEvent);
CloseHandle(hEventTermination);
// Отменяем отображение файла
UnmapViewOfFile(lpFileMap);
// Освобождаем идентификатор созданного
// объекта-отображения
CloseHandle(hFileMapping);
return 0;
}
После создания объектов-событий, предназначенных для синхронизации работы с приложением Fmap/Server, функция main приложения Fmap/Client открывает отображение при помощи функции OpenFileMapping, как это показано ниже:
hFileMapping = OpenFileMapping(
FILE_MAP_READ | FILE_MAP_WRITE, FALSE, lpFileShareName);
В качестве имени отображения здесь указывается строка $MyVerySpecialFileShareName$ - точно такая же, что и в приложении Fmap/Server.
Далее в случае успеха выполняется отображение в память:
lpFileMap = MapViewOfFile(hFileMapping,
FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
Если отображение выполнено успешно, в глобальную переменную lpFileMap записывается указатель на отображенную область памяти, а затем запускается цикл ввода символов с клавиатуры.
Символы вводятся при помощи функции консольного ввода getche. Результат сохраняется в первом байте отображенной области памяти, откуда его будет брать для вывода приложение Fmap/Server:
chr = getche();
if(chr == 27)
break;
*((LPSTR)lpFileMap) = chr;
После выполнения записи функция main устанавливает в отмеченное состояние объект-событие, предназначенное для работы с клавиатурой.
Если пользователь нажимает в окне приложения Fmap/Client клавишу <Esc>, имеющую код 27, цикл прерывается. Оба объекта-события переводятся в отмеченное состояние, после чего идентификаторы этих объектов освобождаются.
Перед завершением работы функция main отменяет отображение файла и освобождает идентификатор объекта-отображения.