Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:OC Windows & OC Linux. Лабораторные работы по курсу «Операционные системы»
.pdf
те адресного пространства, воспользуйтесь функцией GlobalDosAlloc:
DWORD WINAPI GlobalDosAlloc(DWORD cbAlloc);
Параметр cbAlloc определяет размер блока в байтах. Старшее
слово возвращаемого значения содержит сегментную компоненту
адреса реального режима, соответствующего полученному блоку
памяти. Это значение может использоваться для доступа к блоку
памяти в реальном режиме работы процессора.
Младшее слово возвращаемого значения содержит селектор для
доступа к полученному блоку
Для освобождения блока памяти, полученного при помощи
функции GlobalDOSAlloc, следует вызвать функцию GlobalDosFree:
UINT WINAPI GlobalDosFree(UINT uSelector);
В качестве параметра uSelector этой функции следует передать
селекторную компоненту блока памяти, расположенного в первом
мегабайте адресного пространства.
В случае успешного завершения возвращаемое значение равно
нулю. При ошибке возвращается селектор, указанный в параметре
uSelector.
1.2.9. Освобождение
Для освобождения глобального блока памяти, полученного от
функции GlobalAlloc, вы должны использовать функцию GlobalFree:
HGLOBAL WINAPI GlobalFree(HGLOBAL hglb);
Идентификатор освобождаемого блока передается функции в
качестве ее единственного параметра.
Функция возвращает NULL при успешном завершении или значение hglb при ошибке.
Перед освобождением зафиксированных блоков памяти их следует предварительно расфиксировать. Вы можете узнать содержимое
счетчика фиксаций блока при помощи функции GlobalFlags,
описанной выше.
глобального блока памяти
в защищенном режиме.
41

Для освобождения памяти, полученной при помощи макрокоманды GlobalAllocPtr, удобно использовать макрокоманду Global-
FreePtr, описанную в файле windowsx.h:
#define GlobalFreePtr(lp) \
| (GlobalUnlockPtr(lp),(BOOL)GlobalFree(GlobalPtrHandle (lp)))
Данная макрокоманда расфиксирует, а затем и освобождает
блок памяти, заданный своим логическим адресом.
1.2.10. Фиксирование линейного адреса блока памяти
В некоторых случаях вам необходимо запретить изменение линейного адреса блока памяти, которое выполняется в процессе
ремещения. Такое изменение выполняется заменой базового адреса
в соответствующем дескрипторе локальной таблицы дескрипторов.
В результате при перемещении блока логический адрес остается постоянным (так как при перемещении блока ему не присваивается
новый дескриптор, а логический адрес состоит из ссылки на дескриптор, номера запрошенного кольца защиты и смещения), в то
время как линейный может изменяться.
Если драйвер какого-либо устройства ввода/вывода работает с
линейным адресом буфера, память, отведенная для такого буфера, в
некоторых случаях должна быть зафиксирована функцией GlobalFix:
void WINAPI GlobalFix(HGLOBAL hglb);
Параметр функции указывает идентификатор фиксируемого
блока памяти.
Как только отпадет необходимость в фиксировании блока памяти, его следует расфиксировать, вызвав
void WINAPI GlobalUnfix(HGLOBAL hglb);
Единственный параметр этой функции должен содержать идентификатор блока памяти, который будет расфиксирован.
1.3. Локальная динамическая память
Для каждого приложения Windows создается автоматический
сегмент данных размером 64 Кбайт, в котором располагаются стати-
функцию GlobalUnfix:
42
пе-

ческие данные, стек и локальная область данных (local heap). Размер
стека определяется оператором STACKSIZE в файле определения
модуля STACKSIZE 8120.
1.3.1. Получение локального блока памяти
Для получения локального блока памяти вы должны использовать функцию LocalAlloc:
HLOCAL WINAPI LocalAlloc(UINT fuAlloc/ UINT cbAlloc);
Параметр fuAlloc определяет тип выделяемой памяти. Размер
блока памяти в байтах должен передаваться через параметр cbAlloc.
Функция возвращает идентификатор локального блока
или NULL, если Windows не может выделить память указанного
объема.
Параметра fuAlloc должен быть указан как логическая комбинация следующих значений:
Флаг Описание
LMEM_DISCARDABLE Заказывается удаляемый блок памяти.
Этот флаг должен использоваться совместно с флагом LMEM_MOVEABLE
памяти
LMEM_FIXED
LMEM_MOVEABLE
Заказывается фиксированный блок памяти (в защищенном режиме работы
блок памяти будет перемещаемым, даже
если он заказан с использованием флага
LMEM_FIXED, однако в процессе перемещения будет изменяться только линейный адрес, но не логический). Этот
флаг несовместим с флагом LMEM_
MOVEABLE
Заказывается перемещаемый блок памяти. Логический адрес такого блока может изменяться в процессе перемещения. Этот флаг несовместим с флагом
LMEM_FIXED
43

LMEM_NOCOMPACT Для удовлетворения запроса памяти не
следует выполнять объединение всех
свободных участков памяти в один и
удалять блоки памяти, отмеченные как
удаляемые
LMEM_NOD1SCARD Для удовлетворения запроса памяти не
следует выполнять объединение всех
свободных участков памяти в один
LMEM_ZEROINIT
NONZEROLHND Синоним для LMEM_MOVEABLE
NONZEROLPTR Синоним для LMEM_FIXED
Во все байты блока необходимо записать нулевые значения
LHDN
LPTR
1.3.2 Фиксирование и расфиксирование блока памяти
Для получения доступа к полученному блоку памяти его необходимо зафиксировать, вызвав функцию LocalLock :
void NEAR* WINAPI LocalLock(HLOCAL hloc);
Функция LocalLock фиксирует блок памяти, идентификатор которого передается ей через параметр hloc и возвращает логический
адрес зафиксированного блока или NULL, если указанный блок удален или произошла ошибка.
Для каждого блока памяти Windows поддерживает счетчик
фиксирования. Этот счетчик увеличивается при вызове функции
LocalLock и уменьшается при расфиксировании блока функцией
LocalUnlock:
BOOL WINAPI LocalUnlock(HLOCAL hloc);
Синоним для комбинации флагов LMEM
_MOVEABLE и LMEM_ZEROINIT
Синоним для комбинации флагов LMEM
_FIXED и LMEM_ZEROINIT
44

Если содержимое счетчика уменьшилось до нуля, функция возвращает значение FALSE. В противном случае возвращается TRUE.
1.3.3. Определение идентификатора блока памяти по его адресу
С помощью функции LocalHandle вы можете определить идентификатор локального блока памяти:
HLOCAL WINAPI LocalHandle(void NEAR* pvMem);
Параметр pvMem указывает адрес локального блока памяти.
Возвращаемое значение содержит идентификатор локального блока
памяти. В случае ошибки возвращается нулевое значение.
1.3.4. Работа с удаляемыми блоками памяти
Для получения доступа к удаленному локальному блоку памяти
его необходимо восстановить, вызвав функцию LocalReAlloc. Эта
функция аналогична функции GlobalReAlloc и позволяет изменить
характеристики существующего блока памяти.
Приведем
прототип функции LocalReAlloc :
HLOCAL WINAPI LocalReAlloc(HLOCAL hloc, UINT
cbNewSize, UINT fuAlloc);
Параметр hloc указывает идентификатор восстанавливаемого
блока памяти.
При помощи параметра cbNewSize вы должны указать размер
блока памяти, причем можно восстановить удаленный блок памяти
и изменить его размер одновременно.
Параметр fuAlloc определяет тип восстановленного блок памяти. Можно указывать логическую комбинацию следующих флагов:
Флаг Описание
LMEM_DISCARDABLE Если блок памяти был перемещаемый,
то теперь дополнительно он будет и
удаляемый. Этот флаг должен использоваться совместно с флагом
LMEM_MODIFY
45

LMEM_MODIFY
Выполняется изменение характеристик
существующего блока памяти, этот флаг
необходимо указывать вместе с флагами
LMEM_DISCARDABLE и
LMEM_MOVEABLE
MEM_MOVEABLE
LMEM_NODISCARD
LMEM_ZEROINIT
Если раньше указанный блок памяти
был перемещаемым и удаляемым, содержимое счетчика фиксирования для
него равно нулю и новый размер блока
указан равным нулю, данный блок будет
удален. Если же параметр cbNewSize
равен нулю, но блок памяти не является
перемещаемым или удаляемым, функция вернет признак ошибки. Для фиксированного блока
памяти ненулевой длины данный флаг разрешает перемещение,
т.е. преобразует фиксированный блок в
перемещаемый.
Блок памяти не может быть удален операционной системой. Этот флаг должен
использоваться совместно с флагом
LMEM_MODIFY
Если размер блока памяти увеличивается, во все байты дополнительной памяти
необходимо записать нулевые значения.
Этот флаг несовместим с флагом
LMEM_MODIFY
Восстановив блок памяти, вы должны зафиксировать его функ-
цией LocalLock и затем восстановить его прежнее содержимое.
1.3.5 Определение характеристик локального блока памяти
Для определения характеристик локального блока памяти предназначена функция LocalFlags, аналогичная рассмотренной нами
ранее функции GlobalFlags:
UINT WINAPI LocalFlags(HLOCAL hloc);
46

Функция возвращает состояние блока памяти, указанного своим
единственным параметром. Младший байт возвращаемого значения
содержит содержимое счетчика фиксаций блока памяти. В старшем
байте могут быть установлены флаги LMEM_DISCARDABLE и
LMEM_DISCARDED.
Если установлен флаг LMEM_DISCARDABLE, проверяемый
блок памяти может быть удален Windows в процессе дефрагментации свободной области памяти. Если же установлен флаг
LMEM_DISCARDED, удаление блока памяти
уже произошло.
1.3.6. Определение размера блока памяти
С помощью функции LocalSize вы можете определить размер
блока памяти по его идентификатору:
UINT WINAPI LocalSize(HLOCAL hloc);
Эта функция возвращает размер блока памяти, идентификатор
которого задан параметром hloc. Если указанный блок памяти не
существует или удален, возвращается нулевое значение.
1.3.7. Дефрагментация локального блока памяти
Функция LocalCompact выполняет дефрагментацию свободного
пространства
в локальной области данных:
UINT WINAPI LocalCompact(UINT uMinFree);
Функция возвращает размер самого большого доступного непрерывного блока в локальной области памяти, причем, если параметр не равен 0 или –1, выполняется дефрагментация памяти и удаление блоков, отмеченных как удаляемые. Если параметр функции
указан как 0, функция не выполняет дефрагментацию памяти, но
возвращает правильное значение с учетом возможного выполнения
дефрагментации.
1.3.8. Уменьшение размера локального блока памяти
Для уменьшения размера существующего локального блока памяти можно использовать функцию LocalShrink:
UINT WINAPI LocalShrink(HLOCAL hloc, UINT cbNewSize);
47

Параметр hloc указывает идентификатор изменяемого локального блока памяти. Новые размеры блока памяти задаются параметром cbNewSize.
Возвращаемое значение в случае успеха равно новому размеру
блока памяти.
1.3.9. Освобождение локального блока памяти
Для освобождения локального блока памяти, полученного от
функции LocalAlloc, вы должны использовать функцию LocalFree:
HLOCAL WINAPI LocalFree(HLOCAL hloc);
Идентификатор освобождаемого блока передается функции в
качестве ее
Функция возвращает NULL при успешном завершении или значение hloc при ошибке.
Перед освобождением зафиксированных блоков памяти их следует предварительно расфиксировать.
1.3.10. Инициализация локальной области данных в заданном
сегменте
Для создания и инициализации локальной области данных в заданном сегменте вы можете воспользоваться функцией LocalInit:
BOOL WINAPI LocalInit(UINT uSegment, UINT uStartAddr,
UINTuEndAddr);
Параметр uSegment перед вызовом функции
идентификатор сегмента, который будет содержать локальную область данных.
Параметр uStartAddr определяет начальный адрес локальной
области данных, а параметр uEndAddr – конечный адрес локальной
области данных.
Первые 16 байтов в сегменте данных необходимо зарезервировать для системы.
Статические данные, описанные в приложении Windows с использованием ключевого слова static или объявленные как
единственного параметра.
должен содержать
1.4. Статическая память
внешние
48

переменные, располагаются в автоматическом сегменте данных приложения. Операционная система Windows фиксирует сегмент данных при активизации приложения и расфиксирует его во время переключения на другие приложения. Поэтому логический адрес сегмента данных может изменяться.
Рекомендуется использовать ближний статический указатель с
явным преобразованием типа к LPSTR:
static PSTR pstrDlgName = "MyDlg";
........
hDlg = CreateDialog(hInst,
(LPSTR)pstrDlgName / hWndParent, (DLGPROC)
lpDialogProc);
В
процессе явного преобразования типа используется текущее
содержимое регистра DS, а не то, которое использовалось при загрузке приложения в память.
1.5. Автоматическая память
Автоматические данные располагаются, как и статические, в автоматическом сегменте данных, назначаемым приложению при его
загрузке в память. К автоматическим данным относится стек, параметры функций и локальные переменные
Размер стека определяется оператором STACKSIZE в файле определения модуля и не увеличивается автоматически во время работы приложения.
1.6. Дополнительная память в структуре класса окна
При регистрации класса окна вы можете в поле cbClsExtra
структуры WNDCLASS указать размер дополнительной области памяти, которая будет зарезервирована в структуре данных, описывающей класс окна.
значенные для использования всеми окнами, создаваемыми на базе
класса.
Для работы с этой дополнительной памятью предназначены функции SetClassWord, SetClassLong, GetClassWord, GetClassLong.
Функция SetClassWord устанавливает в структуре, описывающей класс для окна hwnd, новое значение wNewWord, при этом
смещение устанавливаемого слова определяется параметром offset:
В эту область можно записать данные, предна-
.
49

WORD WINAPI SetClassWord(HWND hwnd, int offset, WORD
wNewWord);
Для параметра offset вы должны использовать значения от нуля
до указанного в поле cbClsExtra минус 2 или следующие значения:
Значение Описание
GCW_HBRBACKGROUND Идентификатор кисти для закраши-
вания фона окна
GCW_HCURSOR Идентификатор курсора
GCW_HICON Идентификатор пиктограммы
GCW_STYLE Стили окна
С помощью перечисленных выше четырех значений вы можете
изменить характеристики класса окна. Эти изменения будут учитываться только для вновь создаваемых окон.
В случае ошибки функция SetClassWord возвращает нулевое
значение.
Функция GetClassWord позволяет вам прочитать содержимое
слова дополнительной области памяти со смещением offset:
WORD WINAPI GetClassWord(HWND hwnd, int offset);
Для этой функции вы можете использовать те же
значения, что
и для предыдущей, плюс еще два:
Значение Описание
GCW_CBCSLEXTRA
GCW_CBWNDEXTRA
Размер дополнительной области памяти в структуре класса окна
Размер дополнительной области памяти в структуре окна
GCW_HBRBACKGROUND Идентификатор кисти для закраши-
вания фона окна
GCW_HCURSOR Идентификатор курсора
GCW_HICON Идентификатор пиктограммы
GCW_STYLE Стили окна
50
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
