
- •Тема 8. Интерфейсы операционных систем
- •8.1.Интерфейс прикладного программирования
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1.Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1.Основные определения
- •8.1.1.Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1.1. Основные определения
- •8.1. Интерфейс прикладного программирования
- •8.1.2. Классификация системных вызовов
- •Основные функции управления синхронизацией
- •Основные функции управления виртуальной и физической памятью
- •Основные функции управления виртуальной и физической памятью
- •Функции механизма отображения файла в память
- •Основные функции для файлового ввода-вывода
- •Основные функции управления каталогами
- •Некоторые категории вызовов GUI
- •Основные функции управления защитой
- •Основные функции управления реестром
- •Основные функции управления консолью
- •8.1.Интерфейс прикладного программирования
- •8.1.3. Программирование системных вызовов
- •8.1.3.Программирование системных вызовов
- •8.1.3. Программирование системных вызовов
- •8.1.3. Программирование системных вызовов
- •8.1.3.Программирование системных вызовов
- •8.1.3.Программирование системных вызовов
- •8.1.Интерфейс прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •Способы реализации ИПП
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.1.4. Реализация интерфейса прикладного программирования
- •На рис. позицией 1 обозначен вызов обработчика ловушки и диспетчера базовых сервисов. Позиции
- •8.1.4. Реализация интерфейса прикладного программирования
- •8.2. Интерфейс пользователя
- •8.2.1.Типы интерфейсов
- •8.2.1. Типы интерфейсов
- •8.2.1.Типы интерфейсов
- •8.2.1. Типы интерфейсов
- •8.2.1. Типы интерфейсов
- •8.2.1.Типы интерфейсов
- •8.2.1. Типы интерфейсов
- •8.2.Интерфейс пользователя
- •8.2.2.Консоль
- •8.2.2. Консоль
- •8.2.2. Консоль
- •8.2.2. Консоль
- •8.2.2. Консоль
- •8.2.2.Консоль
- •8.2.Интерфейс пользователя
- •8.2.3. Графическая среда
- •8.2.3. Графическая среда
- •8.2.3. Графическая среда
- •8.2.3. Графическая среда
- •8.2.Интерфейс пользователя
- •8.2.Интерфейс пользователя
- •8.2.Интерфейс пользователя
- •8.2.5. Архитектура, управляемая событиями
- •8.2.5. Архитектура, управляемая событиями
- •8.2.5. Архитектура, управляемая событиями
- •8.2.5. Архитектура, управляемая событиями

8.1.4. Реализация интерфейса прикладного программирования
Вызов функций стандартных библиотек языка.
Существуют два основных подхода к реализации передачи и приема фактических параметров. Первый подход отражает стиль языка Си, а второй
-языка Паскаль.
Впервом подходе процедуре не известно, сколько параметров находится в стеке. В этом случае освобождение стека от параметров должна осуществлять вызывающая программа после команды вызова процедуры, например, с помощью таких машинных команд, как POP или ADD ESP.n, где n - длина параметров в байтах.
Второй подход основан на том, что количество параметров фиксировано, а стек можно освободить в вызываемой процедуре. Это достигается выполнением команды RET n, где n - длина параметров в байтах.
ВWindows вызов функций API осуществляется по второй схеме, то есть в стиле языка Pascal. Впрочем, есть и исключения.
Реализация вызова функции DLL-библиотеки может быть
осуществлена двумя способами:
•через динамическое связывание с импортом;
•через динамическое связывание без импорта.
51

8.1.4. Реализация интерфейса прикладного программирования
Вызов функций стандартных библиотек языка.
Суть первого способа заключается в том, что в программу, использующую DLL-библиотеку, включается информация об этой библиотеке. Используя эту информацию, загрузчик операционной системы осуществляет загрузку требуемой DLL-библиотеки в оперативную память и производит связывание программы с функциями библиотеки. И только после этого программе передается управление.
При динамическом связывании без импорта программа не хранит информацию о вызываемых функциях и их DLL-библиотеках. Эта информация предоставляется операционной системе только во время выполнения программы, и связывание программы с функциями также осуществляется во время выполнения.
52

8.1.4. Реализация интерфейса прикладного программирования
Динамическое связывание перед выполнением.
Для динамического связывания перед выполнением, во-первых, необходимо при создании выполнимого файла программы на вход компоновщика, кроме основной программы, файла ресурсов и стандартных библиотек, передать так называемые библиотеки импорта.
Библиотека импорта представляет собой особую форму файла объектной библиотеки. Она используются компоновщиком для разрешения ссылок в исходном коде программы на функции соответствующих DLL- библиотек.
Библиотека импорта описывает состав соответствующей ей DLL- библиотеки, поэтому для каждой DLL-библиотеки существует библиотека с тем же именем, но с расширением .LIB.
Информация о составе DLL-библиотеки необходима компоновщику для установки таблицы косвенных переходов и секции импорта внутри файла .ЕХЕ.
Так, если в программе вызывается функция CreateWindow(), библиотека GDI32.LIB сообщает компоновщику, что данная функция находится в динамически подключаемой библиотеке GDI32.DLL. Поскольку эта информация сохраняется в файле .EXE, Windows может выполнить динамическое связывание программы с библиотекой GDI32.DLL во53время
загрузки программы.

8.1.4. Реализация интерфейса прикладного программирования
Схема создания файла PROGRAM.EXE и используемые при этом библиотеки импорта .LIB.
54

8.1.4. Реализация интерфейса прикладного программирования
Динамическое связывание перед выполнением.
Пример запуска компоновщика для создания программы ргоgram.exe.
С помощью ключа -DEFAULTLIB компоновщику передается информация об используемых DLL-библиотеках.
link.exe –SUBSYSTEM: windows -OUT: program.exe program.obj program.res -DEFAULTLIB: user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib
Библиотеки импорта являются результатом работы компоновщика при создании DLL-библиотек.
Как и объектные библиотеки, библиотеки импорта используются только при разработке программы.
Динамически подключаемые библиотеки используются во время выполнения программы.
Когда выполняется программа, используемая динамически, подключаемая библиотека должна находиться либо на диске, либо в оперативной памяти.
Если библиотеки в памяти нет, то ее файл ищется в следующем порядке:
•в том же каталоге, где находится файл .ЕХЕ программы;
•в текущем каталоге;
•в системном каталоге Windows;
• в каталоге, доступном из переменной PATH в реестре. |
55 |

8.1.4. Реализация интерфейса прикладного программирования
Динамическое связывание перед выполнением.
Врезультате работы компоновщика создается секция импорта idata.
Вэту секцию компоновщик, используя информацию из библиотек импорта, заносит имена вызываемых в программе функций и соответствующих им DLL-библиотек. Каждая строка с именем функции располагается по конкретным адресам.
56

8.1.4. Реализация интерфейса прикладного программирования
Динамическое связывание перед выполнением.
Кроме секции импорта компоновщик в конце секции .text (здесь находится код программы) создает таблицу косвенных переходов. Эта таблица состоит из команд jmp по одной для каждой функции DLL- библиотеки. Каждая команда jmp ссылается на строку секции idata.
Поскольку команда jmp является командой косвенного перехода, то по указанному в команде адресу, например Адрес1, должен находиться также
адрес.
Однако по адресам Адрес1, Адрес2, ....., АдресN в секции idata первоначально расположены строки с именами функций. Поскольку программа еще не получила управления, это несоответствие можно исправить, что и делает Загрузчик ОС.
В ходе загрузки программы в ОП осуществляется динамическая загрузка в память всех используемых, но еще незагруженных DLL- библиотек. После загрузки программы в память в секции импорта на месте имен функций создается таблица адресов используемых функций.
57

8.1.4. Реализация интерфейса прикладного программирования
Динамическое связывание перед выполнением.
Структура программы после ее связывания с DLL-библиотеками. На этом рисунке вместо строки имя_функции-1 записан адрес этой функции в ОП, обозначенный как адрес_функции-1.
58

8.1.4. Реализация интерфейса прикладного программирования
Динамическое связывание перед выполнением.
Теперь динамическое связывание завершено и программа готова к выполнению, поэтому Загрузчик передает ей управление. В процессе выполнения программы будет осуществляться прямая передача управления функциям DLL-библиотек без вмешательства операционной системы.
Пример
Последовательность действий, выполняемых при вызове функции Create Window() (см. рисунки выше).
Перед выполнением команды call параметры функции записываются в стек. Далее команда call сохраняет адрес возврата в стеке и передает управление по адресу Адрес1. По этому адресу находится команда jmp, расположенная в таблице косвенных переходов. Команда jmp, в свою очередь, извлекает содержимое ячейки по адресу Адрес1, то есть адрес вызываемой функции, и передает управление по этому адресу. Адресом передачи управления является адрес_функции-1, а это не что иное, как адрес функции CreateWindow(). Эта функция извлекает параметры, чистит стек, выполняет свою основную работу и в конце выполняет команду ret. Последняя извлекает из стека адрес возврата, записанный командой call, и передает управление на продолжение
выполнения вызывающей программы. |
59 |

8.1.4. Реализация интерфейса прикладного программирования
Динамическое связывание в процессе выполнения.
Динамическое связывание во время выполнения программы применяется в тех случаях, когда на этапе разработки программы не известно, какую DLL-библиотеку следует подключить, или когда известная DLL-библиотека используется опционально.
Предположим, что необходимо выполнить функцию Ellipse3D(), рисующую эллипс в стиле 3D и имеющую формат:
•BOLL Ellipse3D (HDC hdc, int x1, int y1, int x2, int y2); Пусть эта функция принадлежит библиотеке Graph3D.dll.
Вызвать функцию Ellipse3D() традиционным способом нельзя, так как в секции импорта idata отсутствует информация о библиотеке, которой принадлежит эта функции.
Введем новый тип:
•typedef BOOL (WINAPI * PFNELL3D) (HDC, int, int, int, int);
Определим две переменные:
•HMODULE hLibrary; // дескриптор DLL-библиотеки
•PFNELL3D pfnEllipse3D(); // адрес (указатель) функции
60