Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Operatsionnye_sistemy.doc
Скачиваний:
151
Добавлен:
12.03.2015
Размер:
4.94 Mб
Скачать

§ 1.2. Основы программирования в ос Windows

Рассмотрев в предыдущем параграфе многообразие операционных систем для пер-

сональных компьютеров, можно сделать вывод, что программирование в конкретной

операционной системе процесс настолько сложный, основанный на специфических осо-

бенностях данной ОС, что переход программиста на новую операционную систему

практически соизмерим с переходом на новый язык программирования. Поэтому в на-

стоящее время каждый программист является узким специалистом в области програм-

мирования в конкретной ОС, и даже более – в конкретном узком направлении разработ-

ки для данной ОС. При этом общие принципы построения современных ОС

существенно не отличаются друг от друга. Учебное пособие посвящено особенностям

программирования базовых элементов операционных систем и поскольку, в пределах

курса невозможно качественно рассмотреть особенности технологий разработки сис-

28

темных элементов для многих ОС, сосредоточимся в практическом плане на операцион-

ных системах, получивших в настоящее время наибольшее распространение – ОС, раз-

работанных компанией Microsoft – Windows линеек 9x и NT (2000, XP). Таким образом,

в пособии первоначально будут рассматриваться особенности построения базовых эле-

ментов основных современных операционных систем, а далее в более практическом

плане особенности разработки этих технологий в ОС Windows. В качестве базового язы-

ка программирования выбран язык С++ и инструментальная система Visual C++ по сле-

дующим причинам [4]:

- ранее при изучении основ программирования в качестве базового был выбран имен-

но этот язык и инструментальная система, таким образом время, выделенное на изу-

чение курса максимально будет потрачено на изучение основ программирования ба-

зовых элементов ОС, а не на изучение нового языка;

- операционные системы семейства Windows сами были созданы на языке программи-

рования С/С++, поэтому программирование их элементов на данном языке в наи-

меньшей вызовет проблемы совместимости этих элементов;

- большая часть документации, публикаций и других материалов о программировании

для Windows ориентирована на использование C++, фактически вся документация

Microsoft рассчитана на программистов, знакомых именно с этим языком програм-

мирования, который в настоящее время "de facto" стал системным для многих ОС, в

том числе и для Windows;

- в настоящее время большая часть системных программистов во всем мире работает

именно на С/С++.

Вместе с тем, в рабочей среде Windows могут используются многие другие попу-

лярные среды разработки, В частности, получившая в последнее время широкое распро-

странение, среда программирования Java (в первую очередь, при программировании для

Internet). Компания Borland поддерживает собственную среду Delphi, которая основана

на языке Pascal (существует также C++ Builder, которая использует похожий подход к

созданию приложений, но ориентирована на использование C++). Не стоит забывать и

про Visual Basic (VB). Начиная с пятой версии, этот продукт поддерживает полноцен-

ную компиляцию, технологию ActiveX, а также поддерживает прямое обращение к API.

В курсе лекций, посвященных программированию, мы уже научились создавать

различные приложения в среде Windows. В частности научились создавать приложения

на базе однооконного и многооконного интерфейса, обрабатывать сообщения клавиату-

ры и мыши, создавать различные ресурсы, предоставляемые ОС, использовать цветовые

палитры, создавать подключаемые библиотеки и т.д. Все это поможет рассмотреть про-

граммирование базовых системных элементов ОС в более качественной форме. Перво-

начально кратко рассмотрим основы программирования в ОС семейства Windows, об-

щие черты и различия Windows линеек 9x и NT.

1.2.1. Принципы взаимодействия ОС Windows с прикладными программами

Благодаря интерфейсу вызова функций в Windows доступ к системным ресурсам

осуществляется через целый рад системных функций. Совокупность таких функций на-

зывается прикладным программным интерфейсом, или API (Application Programming In-

terfase). Для взаимодействия с Windows приложение запрашивает функции API, с помо-

щью которых реализуются все необходимые системные действия, такие как выделение

памяти, вывод на экран, создание окон и т.п.

Поскольку API состоит из большого числа функций, может сложиться впечатле-

ние, что при компиляции каждой программы, написанной для Windows, к ней подклю-

чается код довольно значительного объема. В действительности это не так. Функции API

содержатся в библиотеках динамической загрузки (Dynamic Link Libraries, или DLL),

29

которые загружаются в память только в тот момент, когда к ним происходит обращение,

т.е. при выполнении программы. Рассмотрим, как осуществляется механизм динамиче-

ской загрузки.

Динамическая загрузка обеспечивает ряд существенных преимуществ.

Во-первых, поскольку практически все программы используют API-функции, то

благодаря DLL-библиотекам существенно экономится дисковое пространство, которое в

противном случае занималось бы большим количеством повторяющегося кода, содер-

жащегося в каждом из исполняемых файлов.

Во-вторых, изменения и улучшения в Windows-приложениях сводятся к обновле-

нию только содержимого DLL-библиотек. Уже существующие тексты программ не тре-

буют перекомпиляции.

В настоящее время наибольшее распространение получила версия API, которая по-

лучила название Win32. Данная версия API пришла на смену версии Win16, используе-

мой в Windows 3.1. Фактически 32-разрядная Win32, используемая в операционных сис-

темах 9x, является надмножеством для Win16 (т.е. фактически включает в себя этот

интерфейс), так как большинство функций имеет то же название и применяется анало-

гичным образом. Однако, будучи в принципе похожими, оба интерфейса все же отлича-

ются друг от друга. Win32 поддерживает 32-разрядную линейную адресацию, тогда как

Win16 работает только с 16-разрядной сегментированной моделью памяти. Это привело

к тому, что некоторые функции были модифицированы таким образом, чтобы прини-

мать 32-разрядные аргументы и возвращать 32-разрядные значения. Часть из них при-

шлось изменить с учетом 32-разрядной архитектуры. Была реализована поддержка по-

токовой многозадачности, новых элементов интерфейса и прочих нововведений

Windows.

Так как Win32 поддерживает полностью 32-разрядную адресацию, то логично, что

целые типы данных (intergers) также объявлены 32-разрядными. Это означает, что пере-

менные типа int и unsigned будут иметь длину 32 бита, а не 16, как в Windows 3.1. Если

же необходимо использовать переменную или константу длиной 16 бит, они должны

быть объявлены как short (далее будет показано, что для этих типов определены незави-

симые typedef-имена.). Следовательно, при переносе программного кода из 16-разрядной

среды необходимо убедиться в правильности использования целочисленных элементов,

которые автоматически будут расширены до 32 битов, что может привести к появлению

побочных эффектов.

Другим следствием 32-разрядной адресации является то, что указатели больше не

нужно объявлять как near и far. Любой указатель может получить доступ к любому уча-

стку памяти. В Windows 9x константы near и far объявлены (с помощью директивы #de-

fine) пустыми.

Существенные изменения коснулись также функций API, которые работают с сим-

вольными строками. Внутренние механизмы Windows 9x (не полностью), NT и Windows

2000 используют символы в формате UNICODE (16-битное значение символов). Но

многие прикладные программы продолжают использовать ANSI (то есть стандарт, в ко-

тором каждый символ кодируется при помощи 8 бит). Чтобы решить эту проблему, каж-

дая функция, работающая со строками, реализована в двух вариантах. В первом вариан-

те в качестве аргумента воспринимается строка в формате ANSI (внутри функции эта

строка автоматически преобразуется в UNICODE). Второй вариант функции напрямую

работает со строками в формате UNICODE.

Одним из подмножеств API является GDI (Graphics Device Interfase – интерфейс

графического устройства). GDI – это та часть Windows, которая обеспечивает поддержку

аппаратно-независимой графики. Благодаря функциям GDI Windows-приложение может

выполняться на различных ПЭВМ.

30

Еще одной особенность Windows является многозадачность, причем поддержива-

ется два типа многозадачности: основанная на процессах и основанная на потоках. Да-

лее идеология многозадачности будет рассмотрена более подробно.

Во многих операционных системах взаимодействие между системой и программой

инициализирует программа. Например, в DOS программа запрашивает разрешение на

ввод и вывод данных. Говоря другими словами, не- Windows-программы сами вызывают

операционную систему. Обратного процесса не происходит. В Windows все совершенно

наоборот: именно система вызывает программу. Это осуществляется следующим обра-

зом: программа ожидает получения сообщения от Windows. Когда это происходит, то

выполняется некоторое действие. После его завершения программа ожидает следующе-

го сообщения.

Windows может посылать программе сообщения множества различных типов. На-

пример, каждый раз при щелчке мышью в окне активной программы посылается соот-

ветствующее сообщение. Другой тип сообщений посылается, когда необходимо обно-

вить содержимое активного окна. Сообщения посылаются также при нажатии клавиши,

если программа ожидает ввода с клавиатуры. Необходимо запомнить одно: по отноше-

нию к программе сообщения появляются случайным образом. Вот почему Windows-

программы похожи на программы обработки прерываний: невозможно предсказать, ка-

кое сообщение появиться в следующий момент.

Функция окна. Все Windows-программы должны содержать специальную функ-

цию, которая не используется в самой программе, но вызывается самой операционной

системой. Эту функцию обычно называют функцией окна, или процедурой окна. Она

вызывается Windows, когда системе необходимо передать сообщение в программу.

Именно через нее осуществляется взаимодействие между программой и системой.

Функция окна передает сообщение в своих аргументах. Согласно терминологии Win-

dows, функции, вызываемые системой, называются функциями обратного вызова. Та-

ким образом, функция окна является функцией обратного вызова. Помимо принятия со-

общения от Windows, функция окна должна вызывать выполнение действия, указанного

в сообщении. Конечно, программа не обязана отвечать на все сообщения, посылаемые

Windows. Поскольку их могут быть сотни, то большинство сообщений обычно обраба-

тывается самой системой, а программе достаточно поручить Windows выполнить дейст-

вия, предусмотренные по умолчанию.

Цикл сообщений. Как объяснялось выше, Windows взаимодействует с програм-

мой, посылая ей сообщения. Все приложения Windows должны организовать так назы-

ваемый цикл сообщений. В этом цикле каждое необработанное сообщение должно быть

извлечено из очереди сообщений данного приложения и передано назад в Windows, ко-

торая затем вызывает функцию окна программы с данным сообщением в качестве аргу-

мента.

Класс окна. Как будет показано далее, каждое окно в Windows-приложении харак-

теризуется определенными атрибутами, называемыми классом окна. (Здесь понятие

“класс” не идентично используемому в С++. Оно, скорее, означает стиль или тип.) В

традиционной программе класс окна должен быть определен и зарегистрирован прежде,

чем будет создано окно. При регистрации необходимо сообщить Windows, какой вид

должно иметь окно и какую функцию оно выполняет. В то же время регистрация класса

окна еще не означает создание самого окна. Для этого требуется выполнить дополни-

тельные действия.

Структура Windows-программ отличается от структуры программ других типов.

Это вызвано двумя обстоятельствами: во-первых, способом взаимодействия между про-

граммой и Windows, описанным выше; во-вторых, правилами, которым следует подчи-

няться для создания стандартного интерфейса Windows-приложения (т.е. чтобы сделать

программу “похожей “ на Windows-приложение).

31

Цель Windows – дать человеку, который хотя бы немного знаком с системой, воз-

можность сесть за компьютер и запустить любое приложение без предварительной под-

готовки. Для этого Windows предоставляет дружественный интерфейс пользователя, ко-

торый необходимо поддерживать всем программистам, создающим программное

обеспечение в данной операционной системе.

1.2.2. Типы данных в Windows

В Windows-программах не слишком широко применяются стандартные типы дан-

ных из С или С++, такие как int или char*. Вместо них используются типы данных, оп-

ределенные в различных библиотечных (header) файлах. Наиболее часто используемыми

типами являются [11]: HANDLE, HWND, BYTE, WORD, DWORD, UNIT, LONG, BOOL,

LPSTR и LPCSTR.

Тип HANDLE обозначает 32-разрядное целое, используемое в качестве дескрипто-

ра. Есть несколько похожих типов данных, но все они имеют ту же длину, что и

HANDLE, и начинаются с литеры Н. Дескриптор – это просто число, определяющее не-

который ресурс.

Тип HWND обозначает 32-разрядное целое – дескриптор окна. В программах, ис-

пользующих библиотеку MFC, дескрипторы применяются не столь широко, как это име-

ет место в традиционных программах.

Тип BYTE обозначает 8-разрядное беззнаковое символьное значение.

Тип WORD – 16-разрядное беззнаковое короткое целое.

Тип DWORD – беззнаковое длинное целое.

Тип UINT - беззнаковое 32-разрядное целое.

Тип LONG эквивалентен типу long.

Тип BOOL обозначает целое и используется, когда значение может быть либо ис-

тинным, либо ложным.

Тип LPSTR определяет указатель на строку.

Тип LPCSTR – константный (const) указатель на строку.

1.2.3. Графический и консольный интерфейс

В Windows поддерживается два типа приложений: основанные на графическом ин-

терфейсе (graphical user interface, GUI) и консольные (console user interface, CUI) У при-

ложений первого типа внешний интерфейс чисто графический - создаются окна, меню,

диалоговые окна и т.д. Почти все стандартные программы Windows и большинство

пользовательских программ являются GUI - приложениями. Приложения консольного

типа работают в текстовом режиме: они не формируют окна, не обрабатывают сообще-

ния, но на экране тоже размещаются в окне, правда черного цвета и могут вызывать диа-

логовые окна.

Все Windows-программы, написанные на языке C++ начинают выполнение с вызо-

ва функции входа. В среде Win32 существует четыре модификации таких функций:

int WINAPI WinMain(

HINSTANCE hInstance, //дескриптор, присваиваемый запущенному приложению

HINSTANCE hPrevInstance, //для совместимости с win16, в win32 не используется

LPSTR lpCmdLine, //указатель на командную строку, если приложение так запущено

int nCmdShow ); //значение, которое может быть передано в функцию ShowWindow()

int WINAPI wWinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

32

LPSTR lpCmdLine,

int nCmdShow);

int _ _cdecl main( int argc, //количество аргументов, переданных в командной строке

char *argv[], //массив размером argc с указателями на ANSI-строки.

//Каждый элемент массива указывает на один из аргументов командной строки

char *envp[] ); //массив указателей на ANSI-строки. Каждый элемент массива

// указывает на строку - переменную окружения (область памяти,

// выделенная в адресном пространстве процесса)

int _ _cdecl wmain( int argc, //количество аргументов, переданных в командной строке

wchar_t *argv[], //массив размером argc с указателями на UNICODE-строки.

//Каждый элемент массива указывает на один из аргументов командной строки

wchar_t *envp[] );//массив указателей на UNICODE-строки. Каждый элемент массива

//указывает на строку - переменную окружения (область памяти, выделенная

//в адресном пространстве процесса)

Первые две функции используются при разработке приложения с графическим ин-

терфейсом (GUI), две другие - при консольном (CUI). Приставка w перед названием

функции показывает, что функция используется для работы с Unicode - строками, обыч-

ные функции работают с ANSI - строками. На самом деле входная функция операцион-

ной системой не вызывается, вместо этого происходит обращение к стартовой функции

из библиотеки С/С++. Она инициализирует библиотеку С/С++, а также обеспечивает

корректное создание любых объявленных глобальных и статических объектов до того,

как начнется выполнение программного кода. В таблице 1.1 показано, в каких случаях

реализуются различные функции входа [7].

Таблица 1.1

Тип приложения

GUI-приложение, работающее с

ANSI-символами и строками

GUI-приложение, работающее с

Unicode-символами и строками

CUI-приложение, работающее с

ANSI-символами и строками

CUI-приложение, работающее с

Unicode-символами и строками

Функция

входа

WinMain()

wWinMain()

Main()

Wmain()

Стартовая функция, встраиваемая в

исполняемый файл

WinMainCRTStartup()

wWinMainCRTStartup()

mainCRTStartup()

wmainCRTStartup()

В целом все стартовые функции выполняют следующие однотипные задачи:

• считывают указатель на полную командную строку нового процесса;

• считывают указатель на переменные окружения нового процесса;

• инициализируют глобальные переменные из библиотеки С/С++

• инициализируют кучу (динамически распределяемую область памяти), используе-

мую С-функциями выделения памяти (malloc, calloc) и другими процедурами низко-

уровневого ввода-вывода;

• вызывают конструкторы всех глобальных и статических объектов С++-классов.

Закончив эти операции, стартовая функция обращается к функции входа.

1.2.4. Создание элементарного графического окна

33

Рассмотрим, как создать элементарное графическое окно в Windows. Как уже ука-

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

Сразу после входа в WinMain() создается и регистрируется класс главного окна прило-

жения. Для этого необходимо заполнить структуру WNDCLASS. Для создания окна ис-

пользуются функции CreateWindow() непосредственно для его создания, ShowWindow()

для визуализации и UpdateWindow() для перерисовки. Все эти функции описаны в файле

windows.h. Рассмотрим структуру WNDCLASS и наиболее значимую функцию Create-

Window() более подробно.

Структура WNDCLASS состоит из 10 полей:

typedef struct tagWNDCLASS

{

UINT cbSize; //размер структуры в байтах

UINT style; //стиль класса окна

WNDPROC lpfnWndProc; // указатель на функцию окна

HINSTANCE hInstance; //дескриптор приложения, которое запускает окно

HICON hIcon; //дескриптор пиктограммы

HCURSOR hCursor; // дескриптор курсора

HBRUSH hbrBackground; // дескриптор кисти для закраски фона

LPCTSTR lpszMenuName; //указатель на строку с именем меню

LPCTSTR lpszClassName; // указатель на строку с именем класса

HICON hIconSm; //дескриптор малой пиктограммы

} WNDCLASS;

Функция CreateWindow() получает на входе 11 параметров:

HWND CreateWindow (

LPCTSTR lpClassName, // зарегистрированное имя класса

LPCTSTR lpWindowName, // имя окна

DWORD dwStyle, // стиль окна

int x, // x -координата позиции окна

int y, // y -координата позиции окна

int nWidth , // ширина окна

int nHeight , // высота окна

HWND hWndParent , // указатель родительского окна

HMENU hMenu , // дескриптор меню, NULL если меню нет

HINSTANCE hInstance , // дескриптор приложения

LPVOID lParam );// данные, которые могут быть переданы создания окна

// NULL если данные не передаются

Для примера рассмотрим исходный текст программы, которая создает элементар-

ное окно в Windows.

#include "windows.h"

#include "windowsx.h"

// функция для управления параметрами создания и уничтожения главного окна

// запуск всех дополнительных элементов окна (если они есть) производится в ней

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM,LPARAM);

// главная функция

34

WINAPI WinMain(

HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

// описываем параметры, которые необходимы для создания окна

HWND hwnd; // указатель класса окна

MSG msg; // Структура MSG содержит информацию

//о сообщениях из очереди потока сообщений.

WNDCLASS w; // структура определяющая класс окна

memset(&w,0,sizeof(WNDCLASS)); //выделение памяти для класса окна

w.style = 0; // стиль окна по умолчанию

w.lpfnWndProc = WndProc; // функция окна

w.hInstance = hInstance; // дескриптор приложения

w.hbrBackground = GetStockBrush(WHITE_BRUSH); // цвет для

//заполнения окна

w.lpszClassName = "API Windows";// имя класса окна

RegisterClass(&w); //Регистрируем класс окна

// Создаем окно

hwnd = CreateWindow("API Windows",//имя класса

"API Windows", //название окна

WS_OVERLAPPEDWINDOW,// стиль окна

10,//x - координата

10,//y- координата

600,//ширина

480,//высота

NULL,//нет родительского окна

NULL,//нет меню

hInstance,//дескриптор приложения

NULL);//не передаем данных

ShowWindow(hwnd,nCmdShow);//активация окна

UpdateWindow(hwnd);//перерисовка

//Цикл обработки сообщений

while(GetMessage(&msg,NULL,0,0))

{

TranslateMessage(&msg); // разрешить использование клавиатуры

DispatchMessage(&msg); // вернуть управление Windows

}

//возвращаемое значении для функции WndProc()

return msg.wParam;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message,

WPARAM wparam,LPARAM lparam)

{

if (Message == WM_DESTROY )

{

PostQuitMessage(0);

return 0;

}

35

}

return DefWindowProc(hwnd,Message,wparam,lparam);

Компиляция и компоновка проекта приводит к созданию exe-файла, запуск которо-

го приводит к появлению окна, представленного на рис.1.1.

Рис.1.1. Результат выполнения программы

1.2.5. Сходства и различия Windows 9x и Windows NT (2000, XP)

Общие черты.

1. Простота использования:

• Автоматическое определение оборудования во время инсталляции и последую-

щей конфигурации

• Интерфейс пользователя нового поколения

• Технология Plug and Play

2.Мощность:

• Реальная многозадачность

• Использование Win32® и OLE

3. Способность совместной работы:

• Встроенная поддержка основных сетевых протоколов (TCP/IP, IPX/SPX, NetBeui)

• Открытая сетевая архитектура и способность выбора типа сетевого клиента,

транспорта, драйверов и расширяемость для поддержки дополнительных сетевых

приложений.

• Встроенные средства предоставления удаленного доступа к рабочей станции

4. Управляемость:

• Открытая архитектура управления с возможностью использования дополнитель-

ных управляющих систем.

• Поддержка стандартов системного управления

• Независимая настройка рабочей области экрана для каждого пользователя и

средства мониторинга.

5. Поддержка приложений:

• Возможность выполнения 16-разрядных Windows приложений

36

• Возможность выполнения 32-разрядных Windows приложений и поддержка OLE

2.0

6. Переносимость

• Полная переносимость на платформы Intel® (386DX, 486, и Pentium® и т.д.)

РазличияWindows 9x и Windows NT приведены в таблице 1.2.

Таблица 1.2

Свойство

Windows 9x Windows NT

Обеспечение полной изоляции 16 битных Windows -

приложений путем предоставления каждому отдель-

ного адресного пространства

Предоставление защиты по стандарту C-2. Отдельные

каталоги и файлы могут быть сделаны невидимыми

для выбранных пользователей.

Установка прав различных пользователей к измене-

нию конфигурации системы.

Защита файловой структуры

нет

нет

нет

нет

да

да

да

да

Автоматическое восстановление после краха системы нет

Поддержка приложений

да

MS DOS

поддержка файловых структур NTFS и HPFS

Поддержка графической библиотеки OpenGL (трех-

мерная графика)

Выполнение IBM® Presentation Manager® (through

1.3) и поддержка стандарта POSIX 1003.2

да

нет

да, начиная с

Windows 98

нет

большинство

да

да

да

Драйверы MS DOS

Драйверы Win16

Компрессия диска

Системные возможности.

да

да

да

нет

нет

да

Поддержка мультипроцессорных платформ

нет

да

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

Команды инженеров для решения проблем в критиче- нет

ских случаях

да

Ежемесячные информационные выпуски

нет

да

Ежеквартальные сервисные пакеты на CD и дискетах нет

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]