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

Модуль WinApi

Модуль WinAPI дает вам непосредственный доступ к расширениям

Borland защищенного режима DOS. Чтобы облегчить написание перено-

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

DLL, разработан интерфейс WinAPI, являющийся подмножеством интер-

фейса API Windows.

Модуль WinAPI позволяет вам использовать функции управления

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

другие функции API. Ниже приведено их краткое описание. Полное

описание констант, типов, процедур и функций модуля WinAPI вы мо-

жете найти в "Справочном руководстве программиста".

При работе под Windows подпрограммы API, поддерживаемые с

помощью модуля WinAPI, находятся в динамически компонуемых библи-

отеках KERNEL.DLL и USER.DLL. В защищенном режиме DOS эти DLL не

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

жима содержит реализацию подпрограмм KERNEL и USER, автоматичес-

ки перенаправляя их вызовы администратору.

Управление памятью

При разработке программ, работающих с динамической памятью,

обычно используются стандартные процедуры New, Dispose, GetMem и

FreeMem. Однако получить доступ к администратору памяти защищен-

ного режима Borland вы можете с помощью функций GlobalXXXX в мо-

дуле WinAPI.

Заметим, что функции GlobalXXXXPtr комбинируют в одной подп-

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

GlobalAlloc, за которыми следуют вызовы GlobalLock, GlobalUnlock

или GlobalFree.

Подпрограммы управления памятью 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 ("Справочник по

библиотеке") "Справочного руководства программиста".

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