Джонсон Харт - Системное программирование в среде Windows
- Название:Системное программирование в среде Windows
- Автор:
- Жанр:
- Издательство:Издательский дом Вильямс
- Год:2005
- Город:Москва • Санкт-Петербург • Киев
- ISBN:5-8459-0879-5
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Джонсон Харт - Системное программирование в среде Windows краткое содержание
Эта книга посвящена вопросам разработки приложений с использованием интерфейса прикладного программирования операционных систем компании Microsoft (Windows 9х, Windows XP, Windows 2000 и Windows Server 2003). Основное внимание уделяется базовым системным службам, включая управление файловой системой, процессами и потоками, взаимодействие между процессами, сетевое программирование и синхронизацию. Рассматривается методика переноса приложений, написанных в среде Win32, в среду Win64. Подробно описываются все аспекты системы безопасности Windows и ее практического применения. Изобилие реальных примеров, доступных также и на Web-сайте книги, существенно упрощает усвоение материала.
Книга ориентирована на разработчиков и программистов, как высокой квалификации, так и начинающих, а также будет полезна для студентов соответствующих специальностей.
Системное программирование в среде Windows - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Обратите также внимание, что выполнение функции библиотеки С exit или возврат из функции main приводят к выходу из процесса.
SEH и обработка исключений в C++
При обработке исключений в C++ используются ключевые слова catch и throw, а сам механизм исключений реализован с использованием SEH. Тем не менее, обработка исключений в C++ и SEH — это разные вещи. Их совместное применение требует внимательного обращения, поскольку обработчики исключений, написанные пользователем и сгенерированные C++, могут взаимодействовать между собой и приводить к нежелательным последствиям. Например, находящийся в стеке обработчик __except может перехватить исключение C++, в результате чего данное исключение так и не дойдет до обработчика C++.
Возможно и обратное, когда, например, обработчик C++ перехватит SEH-исключение, сгенерированное функцией RaiseException. Документация Microsoft рекомендует полностью отказаться от использования обработчиков Windows в программах на C++ и ограничиться применением в них только обработчиков исключений C++.
Кроме того, обработчики исключений или завершения Windows не осуществляют вызов деструкторов, что в ряде случаев необходимо для уничтожения экземпляров объектов C++.
Пример: использование обработчиков завершения для повышения качества программ
Обработчики исключений и завершения позволяют повысить надежность программ как за счет упрощения процедуры восстановления программы после возникновения ошибок и исключений, так и за счет гарантированного освобождения ресурсов и отмены блокирования файлов в критических ситуациях.
В программе toupper (программа 4.2) эти моменты иллюстрируются с привлечением идей, почерпнутых в программном коде предшествующих примеров. toupper обрабатывает несколько файлов, имена которых указываются в командной строке, переписывая их с преобразованием всех букв в верхний регистр. Имена преобразованных файлов получаются путем добавления префикса UC_ к исходным именам, и согласно "спецификации" программы запись поверх существующих файлов не производится. Преобразование файлов осуществляется в памяти машины, поэтому для каждого файла выделяется большая буферная область (достаточная для размещения всего файла). Кроме того, чтобы исключить любую возможность изменения файлов другими процессами, а также для того, чтобы вновь создаваемые выходные файлы строго соответствовали преобразованным входным файлам, оба вида файлов блокируются во время обработки. Понятно, что на каждой стадии обработки существует вероятность возникновения самых различных сбойных ситуаций, но в программе должна быть предусмотрена защита от подобных ошибок, и она должна располагать средствами, позволяющими ей восстановить свое нормальное состояние и попытаться обработать все остальные файлы, имена которых были указаны в командной строке. Программа 4.2 решает все эти задачи, обеспечивая разблокирование файлов во всех необходимых случаях без применения громоздкой логики операторов ветвления, к которым пришлось бы прибегнуть, если бы не были использованы средства SEH. Более подробные комментарии к программе содержатся в программном коде, находящемся на Web-сайте книги.
/* Глава 4. Команда toupper. */
/* Преобразование содержимое одного и более файлов с заменой всех букв на прописные. Имя выходного файла получается из имени входного файла добавлением к нему префикса UC_. */
#include "EvryThng.h"
int _tmain(DWORD argc, LPTSTR argv[]) {
HANDLE hIn = INVALID_HANDLE_VALUE, hOut = INVALID_HANDLE_VALUE;
DWORD FileSize, nXfer, iFile, j;
CHAR OutFileName [256] = "", *pBuffer = NULL;
OVERLAPPED ov = {0, 0, 0, 0, NULL}; /* Используется для блокирования файлов. */
if (argc <= 1) ReportError(_T("Использование: toupper файлы"), 1, FALSE);
/* Обработать все файлы, указанные в командной строке. */
for (iFile = 1; iFile < argc; iFile++) __try { /* Блок исключений. */
/* Все дескрипторы файлов недействительны, pBuffer == NULL, а файл OutFileName пуст. Выполнение этих условий обеспечивается обработчиками. */
_stprintf(OutFileName, "UC_%s", argv[iFile]);
__try { /* Внутренний блок try-finally. */
/* Ошибка на любом шаге сгенерирует исключение, и следующий */
/* файл будет обрабатываться только после "уборки мусора". */
/* Объем работы по очистке зависит от того, в каком месте */
/* программы возникла ошибка. */
/* Создать выходной файл (завершается с ошибкой, если файл уже существует). */
hIn = CreateFile(argv[iFile], GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hIn == INVALID_HANDLE_VALUE) ReportException(argv[iFile], 1);
FileSize = GetFileSize(hIn, NULL);
hOut = CreateFile(OutFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
if (hOut == INVALID_HANDLE_VALUE) ReportException(OutFileName, 1);
/* Распределить память под содержимое файла. */
pBuffer = malloc(FileSize);
if (pBuffer == NULL) ReportException(_T("Ошибка при распределении памяти"), 1);
/* Блокировать оба файла для обеспечения целостности копии. */
if (!LockFileEx(hIn, LOCKFILE_FAIL_IMMEDIATELY, 0, FileSize, 0, &ov) ReportException(_T("Ошибка при блокировании входного файла"), 1);
if (!LockFileEx(hOut, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY, 0, FileSize, 0, &ov) ReportException(_T("Ошибка при блокировании выходного файла "), 1);
/* Считать данные, преобразовать их и записать в выходной файл. */
/* Освободить ресурсы при завершении обработки или возникновении */
/* ошибки; обработать следующий файл. */
if (!ReadFile(hIn, pBuffer, FileSize, &nXfer, NULL)) ReportException(_T("Ошибка при чтении файла"), 1);
for (j = 0; j < FileSize; j++) /* Преобразовать данные. */
if (isalpha(pBuffer [j])) pBuffer[j] = toupper(pBuffer [j]);
if(WriteFile(hOut, pBuffer, FileSize, &nXfer, NULL)) ReportException(T("Ошибка при записи в файл"), 1);
} __finally {
/*Освобождение блокировок, закрытие дескрипторов файлов,*/
/*освобождение памяти и повторная инициализация */
/*дескрипторов и указателя. */
if (pBuffer != NULL) free (pBuffer);
pBuffer = NULL;
if (hIn != INVALID_HANDLE_VALUE) {
UnlockFileEx(hIn, 0, FileSize, 0, &ov);
CloseHandle(hIn);
hIn = INVALID_HANDLE_VALUE;
}
if (hOut != INVALID_HANDLE_VALUE) {
UnlockFileEx(hOut, 0, FileSize, 0, &ov);
CloseHandle(hOut);
hOut = INVALID_HANDLE_VALUE;
}
_tcscpy(OutFileName, _T(""));
}
}
/* Конец основного цикла обработки файлов и блока try. */
/* Обработчик исключений для тела цикла. */
__except(EXCEPTION_EXECUTE_HANDLER) {
_tprintf(_T("Ошибка при обработке файла %s\n"), argv[iFile]);
DeleteFile (OutFileName);
}
_tprintf(_T("Обработаны все файлы, кроме указанных выше \n"));
return 0;
}
Пример: использование функции фильтра
Программа 4.3 представляет собой каркас программы, иллюстрирующей обработку исключений и завершения выполнения, в которой используется функция фильтра. Программа предлагает пользователю указать тип исключения, после чего продолжает работу для генерации исключения. Функция фильтра обрабатывает различные типы исключений по-разному; выбор вариантов, предусмотренных в программе, был совершенно произвольным и определялся исключительно целями демонстрации. В частности, программа обнаруживает попытки обращения к недоступным областям памяти, предоставляя адреса виртуальной памяти, по которым производилось такое обращение.
Читать дальшеИнтервал:
Закладка: