Руководство по языку B.Pascal 7

Подпрограммы управления памятью API


Таблица 17.2 ----------------------T----------------------------------------- ¦ Функция ¦ Описание ¦ +---------------------+-----------------------------------------+ ¦ GetFreeSpace ¦ Определяет объем свободной памяти в ди-¦ ¦ ¦ намически распределяемой области. ¦ +---------------------+-----------------------------------------+ ¦ GlobalAlloc ¦ Выделяет блок памяти в динамически расп-¦ ¦ ¦ ределяемой области. ¦ +---------------------+-----------------------------------------+ ¦ GlobalAllocPtr ¦ Выделяет и блокирует блок памяти (с по-¦ ¦ ¦ мощью вызовов GlobalAlloc и GlobalLock).¦ ¦ ¦ ¦ +---------------------+-----------------------------------------+ ¦ GlobalCompact ¦ Переупорядочивает память, распределен-¦ ¦ ¦ ную в динамической области, так что ос-¦ ¦ ¦ вобождается заданный объем памяти. ¦ +---------------------+-----------------------------------------+ ¦ GlobalDiscard ¦ Выгружает заданный объект памяти. ¦ +---------------------+-----------------------------------------+ ¦ GlobalDosAlloc ¦ Распределяет память, к которой можно по-¦ ¦ ¦ лучить доступ в реальном режиме DOS. Эта¦ ¦ ¦ память будет существовать в первом мега-¦ ¦ ¦ байте линейного адресного пространства. ¦ +---------------------+-----------------------------------------+ ¦ GlobalDosFree ¦ Освобождает память, выделенную ранее с¦ ¦ ¦ помощью GlobalDosAlloc. ¦ +---------------------+-----------------------------------------+ ¦ GlobalFlags ¦ Получает информацию о блоке памяти. ¦ +---------------------+-----------------------------------------+ ¦ GlobalFree ¦ Освобождает разблокированный блок памяти¦ ¦ ¦ и делает его описатель недействительным.¦ +---------------------+-----------------------------------------+ ¦ GlobalFreePtr ¦ Разблокирует и освобождает блок памяти¦ ¦ ¦ с помощью GlobalUnlock и GlobalFree. ¦ +---------------------+-----------------------------------------+ ¦ GlobalHandle ¦ Получает описатель объекта в памяти по¦ ¦ ¦ заданному адресу сегмента. ¦ +---------------------+-----------------------------------------+ ¦ GlobalLock ¦ Увеличивает счетчик ссылки блока памяти¦ ¦ ¦ и возвращает указатель на него. ¦ +---------------------+-----------------------------------------+ ¦ GlobalLockPtr ¦ То же, что и GlobalLock, но вместо опи-¦ ¦ ¦ сателя воспринимает указатель. ¦ +---------------------+-----------------------------------------+ ¦ GlobalLRUNewest ¦ Перемещает объект в памяти на новую не-¦ ¦ ¦ давно используемую позицию, минимизируя,¦ ¦ ¦ таким образом, вероятность выгрузки¦ ¦ ¦ объекта. ¦ +---------------------+-----------------------------------------+ ¦ GlobalLRUOldest ¦ Перемещает объект в памяти на самую¦ ¦ ¦ "старую" недавно используемую позицию,¦ ¦ ¦ максимизирую вероятность выгрузки объ-¦ ¦ ¦ екта. ¦ +---------------------+-----------------------------------------+ ¦ GlobalNorify ¦ Вызывает адрес экземпляра процедуры уве-¦ ¦ ¦ домления, передавая описатель блока, ко-¦ ¦ ¦ торый нужно выгрузить. ¦ +---------------------+-----------------------------------------+ ¦ GlobalPageLock ¦ Увеличивает значение счетчика блокиров-¦ ¦ ¦ ки для памяти, связанной с данным селек-¦ ¦ ¦ тором. ¦ +---------------------+-----------------------------------------+ ¦ GlobalPageUnlock ¦ Уменьшает значение счетчика блокировки¦ ¦ ¦ для памяти, связанной с данным селекто-¦ ¦ ¦ ром. ¦ +---------------------+-----------------------------------------+ ¦ GlobalPtrHandle ¦ По заданному указателю на блок памяти¦ ¦ ¦ возвращает описатель этого блока. ¦ +---------------------+-----------------------------------------+ ¦ GlobalReAlloc ¦ Перераспределяет блок памяти. ¦ +---------------------+-----------------------------------------+ ¦ GlobalReAllocPtr ¦ Разблокирует, перераспределяет и блоки-¦ ¦ ¦ рует блок памяти (используя функции¦ ¦ ¦ GlobalUnlock, GlobalReAlloc и¦ ¦ ¦ GlobalLock). ¦ +---------------------+-----------------------------------------+ ¦ GlobalSize ¦ Определяет текущий размер блока памяти. ¦ +---------------------+-----------------------------------------+ ¦ GlobalUnfix ¦ Разблокирует блок памяти, блокированный¦ ¦ ¦ ранее с помощью GlobalLock. ¦ +---------------------+-----------------------------------------+ ¦ GlobalUnockPtr ¦ То же, что и GlobalUnlock, но вместо¦ ¦ ¦ описателя воспринимает указатель. ¦ +---------------------+-----------------------------------------+ ¦ LockSegment ¦ Блокирует заданный выгружаемый сегмент. ¦ +---------------------+-----------------------------------------+ ¦ UnlockSegment ¦ Разблокирует сегмент. ¦ L---------------------+------------------------------------------


Функция GlobalAlloc используется для распределения блоков памяти. Для их освобождения применяется функция GlobalFree. Адми- нистратор памяти поддерживает три типа блоков памяти: фиксирован- ный, перемещаемый и выгружаемый. Фиксированный блок остается в одних и тех же адресах физической памяти. Перемещаемый блок может перемещаться в физической памяти и освобождать место для других запросов на выделение памяти, а выгружаемые блоки могут выгру- жаться из памяти, освобождая место для других блоков. С помощью передаваемых GlobalAlloc флагов вы можете выбрать один из этих трех типов:

* gmem_Fixed (фиксированный) * gmem_Moveable (перемещаемый) * gmem_Moveable + gmem_Discardable (выгружаемый)

Прикладная программа обычно выделяет только перемещаемые блоки памяти, которые представляются типом THandle в модуле WinAPI. Описатель памяти - это значение размером в слово, которое идентифицирует блок памяти аналогично тому, как описатель файла - это значение размером в слово, идентифицирующее открытый файл.

Перед тем как вы сможете получить доступ к памяти, его нужно заблокировать с помощью функции GlobalAlloc, а когда вы закончите к нему обращаться, его нужно разблокировать с помощью функции GlobalUnlock. GlobalLock возвращает полный 32-разрядный указатель на первый байт блока. Смещение указателя всегда равно 0. В защи- щенном режиме DOS селектор указателя - это тоже самое, что описа- тель блока, но в Windows это не всегда так.

Правильная последовательность вызовов для выделения, блоки- ровки, разблокировки или освобождения блока показана в приведен- ном ниже примере. В данном примере H - это переменная типа THandle, а P - указатель:

H := GlobalAlloc(gmem_Moveable, 8192); { выделение блока } if H <> then { если память выделена } begin P := GlobalLock(H); { блокировка блока } . . { доступ к блоку через P } . GlobalUnlock(H); { разблокировать блок } GlobalFree(H); { освободить блок } end;

Блокировка и разблокировка блока при каждом обращении к нему достаточно утомительна и ведет к ошибкам, и реально она необходи- ма только для выгружаемых блоков и в прикладных программах Windows, работающих в реальном режиме. Во всех других ситуациях лучшим решением является блокировка блока сразу после его выделе- ния и сохранение этого состояния до освобождения блока. С этой целью модуль WinAPI включает в себя семейство подпрограмм-"оболо- чек" GlobalXXXXPtr. Особый интерес представляет функция GlobalAllocPtr, которая выделяет и блокирует блок памяти, и функ- ция GlobalFreePtr, разблокирующая и освобождающая блок памяти. С помощью этих подпрограмм приведенный выше пример можно упростить:



H := GlobalAlloc(gmem_Moveable, 8192); { выделение блока } if H <> then { если память выделена } begin . . { доступ к блоку } . GlobalFreePtr(P); { освободить блок } end;

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

GlobalReAlloc возвращает новый описатель блока, который может от- личаться от передаваемого функции описателя, если старый размер или новый размер блок превышает 64К. Заметим, что в тех случаях, когда старый размер блока и новый его размер меньше 64К, GlobalReAlloc всегда может изменить размер блока, не изменяя его описателя.

Функция GlobalReAlloc можно также использоваться для измене- ния атрибутов блока. Это можно сделать, задав наряду с gmem_Moveable или gmem_Discardable флаг gmem_Modify.

Функция GlobalReAlloc выполняет те же действия, что и GlobalReAlloc, но обе они вместо описателей использует указатели.

Имеется также ряд других, менее часто используемых GlobalXXXX. Все они подробно описаны в Главе 1 ("Справочник по библиотеке") "Справочного руководства программиста".


Содержание раздела