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

Рихтер Дж., Назар К. - Windows via C C++. Программирование на языке Visual C++ - 2009

.pdf
Скачиваний:
6265
Добавлен:
13.08.2013
Размер:
31.38 Mб
Скачать

Оглавление XV

И вот тут мы подходим к тому, о чем же моя книга. А она — о строительных кирпичиках Windows, базовых сервисах, в которых (по крайней мере, на мой взгляд) должен досконально разбираться каждый разработчик Windows-приложений. Рассматривая тот или иной сервис, я буду рассказывать, как им пользуется система и как им должно пользоваться ваше приложение. Во многих главах я буду показывать, как на основе базовых сервисов Windows создавать собственные строительные кирпичики. Реализуя их в виде универсальных функций и классов С++ и комбинируя в них те или иные базовые сервисы Windows, вы получите нечто большее суммы отдельных частей.

64-разрядные версии Windows

В течение долгого времени Майкрософт поставляла 32-разрядные версии Windows для компьютеров с процессорами архитектуры xS6. Сейчас Майкрософт поставляет 64-разрядные версии операционные системы Windows, поддерживающие процессоры с архитектурой x6A и IA64. Компьютеры на основе 64-разрядных процессоров быстро завоевывают популярность. Ожидается, что в самом близком будущем такими процессорами будут оснащены все рабочие станции и серверы. Поэтому Майкрософт заявляет, что Windows Server 2008 станет последней 32-разрядной версией Windows! Стало быть, и разработчики должны писать свои программы так, чтобы они корректно работали с 64-разрядными версиями Windows. Многое из того, что нужно знать для создания программ, совместимых с 64-разрядной (и 32-разрядной) Windows вы найдете в этой книге.

Основное преимущество 64-разрядного адресного пространства — возможность легко манипулировать большими объемами данных, поскольку размер доступного адресного пространства для 64-разрядной системы не ограничен 2 Гб. Даже если вашему приложению столько не нужно, увеличение адресного пространства (до 8 Тб), несомненно, пойдет на пользу Windows, которая станет работать быстрее.

Вот что, вкратце, следует знать о 64-разрядных версиях Windows:

Ядро 64-разрядной Windows — это ядро 32-разрядной Windows, портированное на 64-разрядную платформу. Это означает, что все механизмы и хитрости программирования, знакомые вам по 32-разрядной версии, будут работать и в 64-разрядном «мире». В действительности, Майкрософт компилирует 32- и 64-разрядные версии из одного и того же исходного кода. Иными словами, у этих версией единая база кода, и все новые возможности и исправления появляются в двух версиях одновременно.

Поскольку обе платформы используют одного и то же ядро и одинаковые базовые концепции, Windows API также идентичен на обеих платформах. Следовательно, вам не придется заново проектировать и переписывать свои приложения, чтобы заставить их работать в 64-разрядной Windows — достаточного внести в код небольшие изменения и перекомпилировать его.

XVI Оглавление

Для сохранения преемственной совместимости 64-разрядная Windows поддерживает исполнение 32-разрядных приложений, однако их производительность на 64-разрядной платформе увеличится после перекомпиляции для этой платформы.

Поскольку перенос 32-разрядного кода в 64-разрядную Windows оказался несложным делом, уже доступно немало драйверов устройств, утилит и приложений для 64-разрядной версии. Visual Studio — это «родное» 32-разрядное приложение, но Майкрософт, похоже, спешит сделать из него 64-разрядное приложение. К счастью, и 32-разрядная Visual Studio неплохо работает в 64-разрядной Windows, просто для нее действует то же ограничение на размер доступного адресного пространства, что и для всех 32-разрядных программ. Еще один плюс Visual Studio в том, что она позволяет отлаживать 64-разрядные приложения.

В 64-разрядной Windows не так уж много нового. Вас должно обрадовать, что многие типы данных, включая int, DWORD, LONG, BOOL и ряд других, останутся 32-разрядным. Беспокоиться об указателях и описателях тоже не придется, поскольку теперь все они 64-разрядные.

Сведений о том, как подготовить исходный код к выполнению на 64-разрядной платформе, вполне хватает и на веб-сайте Майкрософт, так что я в эти детали вдаваться не буду. Но, что бы я ни писал в каждой главе, я все время помнил о 64-разрядной Windows и, где это было нужно, включал специфическую для нее информацию. Кроме того, все приведенные в этой книге программы-примеры я компилировал с использованием 64-разрядного компилятора. Если вы будете следовать тем же правилам, что и я, вам не составит труда создать единую базу исходного кода своих приложений для 32- и 64-разрядной Windows.

Что нового в пятом издании

Традиционно названия новых изданий этой книги отличались от предыдущих: Advanced Windows NT, Advanced Windows и Programming Applications for Microsoft Windows… И

эта книга, получив название Windows via С/С++, не стала исключением. Из названия ясно, что она предназначена для программистов на языках С и С++, желающих разобраться в Windows. В новом издании описано более 170 новых функций, появившихся в

Windows XP, Windows Vista и Windows Server 2008.

Некоторые главы полностью переписаны, например глава 11, посвященная работе с новым API пула потоков. Остальные главы были существенно доработаны и дополнены новыми сведениями. Так, в главу 4 добавлено описание механизма User Account Control, а в главу 8 — описание новых синхронизирующих механизмов (таких как Interlocked

Singly-Linked List, Slim Reader-Writer Lock и условные переменные).

 

Намного детальнее я рассказываю и

о том, как взаимодействует

с систе-

мой библиотека С/С++ (С/С++ run-time

library) — особенно при

реализа-

Оглавление XVII

ции защитных механизмов и обработке исключений. Наконец, я добавил две совершенно новые главы: о механизмах ввода-вывода и о работе новой системы Windows Error Reporting, изменившей подходы к созданию отчетов об ошибках и восстановлению приложений после сбоев.

Помимо этих изменений, в книге появилась целая тонна нового содержания. Упомяну лишь самое главное.

Новшества Windows Vista и Windows Server 2008. Книгу было бы нельзя считать действительно переработанной, не будь в ней отражены новшества Windows XP, Windows Vista, Windows Server 2008 и библиотеки С/С++: безопасные строковые функции, изменения объектов ядра (дескрипторы границ и пространства имен), списки атрибутов потоков и процессов, планирование операций ввода-вывода, отмена синхронного ввода-вывода, векторная обработка исключений и многое другое.

Поддержка 64-разрядной Windows. В книге приводится информация, специфическая для 64-разрядной Windows; все программы-примеры построены с учетом специфики этой версии Windows и протестированы в ней.

Применение С++. По требованию читателей примеры написаны на С++. В итоге они стали компактнее и легче для понимания.

Повторно используемый код. Я старался писать по возможности универсальный код, пригодный для многократного использования. Это позволит вам брать из него от дельные функции или целые C++-классы без изменений (незначительная модификация может понадобиться лишь в отдельных случаях). Код на С++ гораздо проще для повторного использования.

Утилита ProcessInfo теперь отображает владельца процесса, командную строку и сведения об UAC.

Утилита LockCop — новинка этого издания. Она отображает работающие в системе процессы, а при выборе процесса — список его потоков с указанием синхронизирующего механизма, используемого каждым потоком. При этом утилита определяет и показывает взаимные блокировки

Перехват API-вызовов. Я представлю вам несколько С++-классов, которые сделают перехват API-вызовов в одном или всех модулях процесса тривиальной задачей. Вы сможете перехватывать даже вызовы Load-Library и GetProcAddress от библиотеки С/С++!

Более подробные сведения о структурной обработке исключений. Эту часть я тоже переписал и во многом перестроил. Вы найдете здесь больше информации о необрабатываемых исключениях и познакомитесь с настройкой отчетов, генерируемых службой Windows Error Reporting, под свои потребности.

XVIII Оглавление

Примеры кода и требования к системе

Примеры кода для этой книги можно загрузить с веб-сайта поддержки по адресу: http://www.wintellect.com/books.aspx

Для компиляции примеров потребуется Visual Studio 2005 или выше, Microsoft

Platform SDK для Windows Vista и Windows Server 2008 (поставляется с некоторыми версиями Visual Studio). Для запуска приложений необходим компьютер (или виртуальная машина) под управлением Windows Vista.

Техническая поддержка

Я и мои редакторы сделали все возможное, чтобы в этой книге и примерах было как можно меньше ошибок. Исправления замеченных неточностей будут публиковаться на сайте:

http://www.wintellect.com/books.aspx

Microsoft Press публикует исправления на http://mspress.microsoft.com/support.

Если у вас есть какие-нибудь комментарии, вопросы или идеи, касающиеся моей книги, пожалуйста, направляйте их в Microsoft Press по обычной или электронной почте:

Microsoft Press

Attn: Windows via C/C++ Editor One Microsoft Way

Redmond, WA 98052-6399 mspinput@microsoft.com

Ч А С Т Ь I

МАТЕРИАЛЫ ДЛЯ ОБЯЗАТЕЛЬНОГО ЧТЕНИЯ

Оглавление

 

Г Л А В А 1 Обработка ошибок ................................................................................................................

2

Вы тоже можете это сделать...................................................................................................................

7

Программа-пример ErrorShow................................................................................................................

8

Г Л А В А 1

Обработка ошибок

Прежде чем изучать функции, предлагаемые Microsoft Windows, посмотрим, как в них устроена обработка ошибок.

Когда вы вызываете функцию Windows, она проверяет переданные ей параметры, а затем пытается выполнить свою работу. Если вы передали недопустимый параметр или если данную операцию нельзя выполнить по какой-то другой причине, она возвращает значение, свидетельствующее об ошибке. В таблице 1-1 показаны типы данных для возвращаемых значений большинства функций Windows.

Табл. 1-1. Стандартные типы значений, возвращаемых функциями Windows

Тип данных

Значение, свидетельствующее об ошибке

VOID

Функция всегда (или почти всегда) выполняется успешно. Таких функций в

 

Windows очень мало

BOOL

Если вызов функции заканчивается неудачно, возвращается 0; в остальных

 

случаях возвращаемое значение отлично от 0 (не пытайтесь проверять его на

 

соответствие TRUE, лучше проверить его на соответствие FALSE)

HANDLE

Если вызов функции заканчивается неудачно, то обычно возвращается NULL; в

 

остальных случаях HANDLE идентифицирует объект, которым Вы можете ма-

 

нипулировать. Будьте осторожны: некоторые функции возвращают HANDLE

 

со значением INVALID_HANDLE_VALUE, равным -1. В документации Plat-

 

form SDK для каждой функции четко указывается, что именно она возвращает

 

при ошибке — NULL или INVALID_HANDLE_VALUE

PVOID

Если вызов функции заканчивается неудачно, возвращается NULL; в осталь-

 

ных случаях PVOID сообщает адрес блока данных в памяти

 

Глава 1. Обработка ошибок.docx 3

Табл. 1-1. (окончание)

 

Тип данных

Значение, свидетельствующее об ошибке

LONG Это значение — «крепкий орешек». Функции, которые сообщают или DWORD значения каких-либо счетчиков, обычно возвращают LONG или DWORD. Если по какой-то причине функция не сумела сосчитать то, что вы хотели, она обычно возвращает 0 или -1 (все зависит от конкретной функции). Если вы используете одну из таких функций, проверьте по документации Platform SDK, каким именно значением она уведомляет об ошибке

При возникновении ошибки вы должны разобраться, почему вызов данной функции оказался неудачен. За каждой ошибкой закреплен свой код — 32-битное число.

Функция Windows, обнаружив ошибку, через механизм локальной памяти потока сопоставляет соответствующий код ошибки с вызывающим потоком. (Локальная память потока рассматривается в главе 21) Это позволяет потокам работать независимо друг от друга, не вмешиваясь в чужие ошибки. Когда функция вернет вам управление, ее возвращаемое значение будет указывать на то, что произошла какая-то ошибка. Какая именно — вы узнаете, вызвав функцию

GetLastError.

DWORD GetLastError();

Она просто возвращает 32-битный код ошибки для данного потока.

Теперь, когда у вас есть код ошибки, вам нужно обменять его на что-нибудь более внятное. Список кодов ошибок, определенных Майкрософт, содержится в заголовочном файле WinError.h. Я приведу здесь его небольшую часть, чтобы вы представляли, на что он похож:

//MessageId: ERROR_SUCCESS

//MessageText:

//

// The operation completed successfully.

//

 

#define ERROR_SUCCESS

0L

#define N0_ERR0R 0L

// dderror

#define SEC_E_OK

((HRESULT)OxOOOOOOOOL)

//

//MessageId: ERROR_INVALID_FUNCTION

//MessageText:

//

// Incorrect function.

4 Часть I. Материалы для обязательного чтения

//

#define ERROR_INVALID_FUNCTION 1L // dderror

//

//MessageId: ERROR_FILE_NOT_FOUND

//MessageText:

//

// The system cannot find the file specified.

//

#define ERROR_FILE_NOT_FOUND 2L

//

//MessageId: ERROR_PATH_NOT_FOUND

//MessageText:

//

// The system cannot find the path specified.

//

#define ERROR_PATH_NOT_FOUND 3L

//

//MessageId: ERROR_TOO_MANY_OPEN_FILES

//MessageText:

//

// The system cannot open the file.

//

#define ERROR_TOO_MANY_OPEN_FILES 4L

//

//MessageId: ERROR_ACCESS_DENIED

//MessageText:

//

 

// Access is denied.

 

//

 

#define ERROR_ACCESS_DENIED

5L

Как видите, с каждой ошибкой связаны идентификатор сообщения (его можно использовать в исходном коде для сравнения со значением, возвращаемым GetLastError), текст сообщения (описание ошибки на нормальном языке) и номер (вместо него лучше использовать идентификатор). Учтите, что я показал лишь крошечную часть файла WinError.h; на самом деле в нем более 39 000строк!

Функцию GetLastError нужно вызывать сразу же после неудачного вызова функции Windows, иначе код ошибки может быть потерян (перезаписан

Соседние файлы в предмете Программирование на C++