Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
5
Добавлен:
26.02.2022
Размер:
141.58 Кб
Скачать

Вариант 1

Задание:

Требуется написать программу для обмена текстовыми сообщениями между экземплярами через проецируемые в память файлы, которая:

1.Запрашивает у пользователя наименование разделяемой области памяти.

2.Пытается открыть указанную область функцией OpenFileMapping(); если области не существует,

создает её функцией CreateFileMapping().

Указание. Отсутствие разделяемой области памяти можно диагностировать, если функция OpenFileMapping() завершилась ошибкой с соответствующим кодом (который можно получить функцией GetLastError()). Узнать нужный код ошибки можно по MSDN.

3.Проецирует участок разделяемой области памяти фиксированного размера.

4.Запрашивает у пользователя, что следует сделать:

4.1.Записать строку в разделяемую область памяти. Необходимо предложить пользователю ввести строку, а затем записать в спроецированный участок разделяемой памяти.

4.2.Считать строку в разделяемую область памяти. Необходимо вывести на экран содержимое спроецированного участка памяти как строку.

4.3.Завершить работу. Необходимо закончить проецирование функцией UnmapViewOfFile()

иотключиться от открытой или созданной разделяемой области памяти функцией CloseHandle().

5.Проверить экспериментально и отразить результаты в отчете возможность работы

со спроецированной областью файла после того, как завершилась создавшая эту область программа (из программ, которые открыли эту область еще при её работе).

Пример работы программы — процесс No 1:

Enter mapping name: communication Connecting to `communication'... failed. Creating new mapping `comminication'. Enter 1 for writing, 2 for reading, 3 for exit: 1 Enter the message: Hello!

Enter 1 for writing, 2 for reading, 3 for exit:

Пример работы программы — процесс No 2:

Enter mapping name: communication Connecting to `communication'... done. Enter 1 for writing, 2 for reading, 3 for exit: 2 The message is `Hello!'.

Указание. Целесообразно взять за основу официальный пример работы с разделяемой областью памяти, соединив две представленные в нем программы в одну:

https://docs.microsoft.com/ru-ru/windows/win32/memory/creating-named-shared-memory?redirectedfrom=MSDN

Выполнение

#include <windows.h> #include <iostream> #include <string>

#define MAX_BUFFER_SIZE 256

//Реализация ввода буквы для выбора действия int inputChoice()

{

int result;

std::cout << "Enter a letter: ";

1

result = std::cin.get(); std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); return std::tolower(result);

}

int main()

{

std::string mapping_name;

std::cout << "Enter shared memory name: "; //Запрос наименования разделяемой области памяти std::getline(std::cin, mapping_name);

DWORD err = ERROR_SUCCESS;

std::cout << "Connecting to '" << mapping_name << "' ... ";//Попытка открыть указанную область auto mapped = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, mapping_name.c_str());

if (!mapped)

{

err = GetLastError(); std::cout << "failed.\n";

if (err == ERROR_FILE_NOT_FOUND)

{

std::cout << "Creating '" << mapping_name << "'.\n";

mapped = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, MAX_BUFFER_SIZE, mapping_name.c_str()); //Создание указанной области

err = GetLastError();

if (err != ERROR_SUCCESS)

{

std::cout << "\nError. Error code: " << err << '\n'; return EXIT_FAILURE;

}

}

}

//Проецирование участка разделяемой области памяти

auto buf = static_cast<char*>(MapViewOfFile(mapped, FILE_MAP_ALL_ACCESS, 0, 0, MAX_BUFFER_SIZE));

err = GetLastError(); if (!buf)

{

std::cout << "Error. Error code: " << err << '\n'; CloseHandle(mapped);

return EXIT_FAILURE;

}

//Реализация выбора действия int choice = 0;

std::string message; do

{

std::cout << "\nPlease, choose an action to do:\n"

<<"\tR)ead message from shared memory;\n"

<<"\tW)rite message to shared memory;\n"

<<"\tQ)uit.\n";

choice = inputChoice(); switch (choice)

{

2

case 'r': //Считывание строки в разделяемую область памяти std::cout << "The message says:\n\t" << buf;

break;

case 'w': //Запись строки в разделяемую область памяти std::cout << "Enter message text: ";

std::getline(std::cin, message);

if (message.size() > MAX_BUFFER_SIZE - 1)

{

//Если сообщение слишком длинное, осуществляется его сокращение

std::cout << "Message is too big. Cutting it off to " << MAX_BUFFER_SIZE - 1 << " symbols.\n"; message.resize(MAX_BUFFER_SIZE - 1);

}

strcpy(buf, message.c_str()); std::cout << "OK, message is sent."; break;

case 'q': //Завершение работы break;

default:

std::cout << "Please, enter R, W or Q!\n"; break;

}

std::cout << '\n';

} while (choice != 'q');

UnmapViewOfFile(buf); //Завершение проецирования CloseHandle(mapped); //Отключение от разделяемой области памяти return EXIT_SUCCESS;

}

3

Соседние файлы в папке Windows лаб 1-4