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

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

Для модуля Graph предусмотрены две программы управления ди-

намически распределяемой областью GraphFrееМем и GraphGetМем.

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

вторая - распределяет память для драйверов графических устройств.

Стандартные программы имеют следующий вид:

procedure GraphGetMem(var P : Pointer; Size : word);

{ выделить память для драйверов графических устройств }

procedure GraphFreeMem(var P : Pointer; Size : word);

{ освободить память для драйверов графических устройств }

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

указывают на две описанные здесь стандартные подпрограммы. Эти

указатель определяются следующим образом:

var

GraphGetMemPtr : pointer;

{ указатель на программу распределения памяти }

GraphFreeMemPtr : pointer;

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

Во время инициализации модуля Graph эти указатели ссылаются

на стандартные графические программы распределения/освобождения,

которые определяются в секции реализации модуля Graph. Память

распределятся в трех различных целях:

* для многоцелевых графических буферов, размер которых уста-

навливается вызовов SegGraphBufSize (по умолчанию это 4К);

* для драйвера устройства, загружаемого InitGraph (файлы

*.BGI);

* для файла векторного шрифта, загруженного SetTextStyle

(файлы *.CHR).

Графический буфер всегда выделяется в динамически распреде-

ляемой области памяти. Память для драйвера устройства выделяется

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

компонуется с ним вызовом RegisterBGIdriver. При выборе векторно-

го шрифта с помощью SetTextStyle также выделяется память в дина-

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

ся со шрифтом и не использует RegisterBGIfont).

Чтобы задать ваше собственное управление памятью, в модуле

Graph вы можете изменить значения этих указателей так, чтобы они

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

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

дартные программы, и должны иметь дальний тип вызова. Приведем

далее пример заданных пользователем программ распределения и ос-

вобождения памяти. Заметим, что при использовании процедуры Eхit

автоматически вызывается процедура CloseGraph.

program UserHeapManegement;

{ программа показывает, как пользователь может работать с

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

ластью памяти, используемыми в модуле Graph }

uses

Graph;

var

GraphDriver, GraphMode : Integer;

ErrorCode : Integer; { используется для

сохранения кода возврата функции GraphResult }

PreGraphExitProc : Pointer { используется для сох-

ранения исходной процедуры выхода }

{ процедуры пользователя должны использовать дальний тип

обращения }

procedure MyGetMem(var P : Pointer; Size : word); far;

{ выделить память для драйверов графических устройств }

begin

Write('Была вызвана процедура ',

'MyGetMem, нажмите <Enter>:');

GetMem(P, Size);

end; { MyGetMem }

procedure MyFreeMem(ver P : Pointer; Size : word); far;

{ освободить память, занятую драйверами графических

устройств }

begin

RestoreCRTMode;

Write('Была вызвана процедура MyFreeMem, нажмите ',

'<Enter>:'); Readln;

if P <> Nil Then { не освобождать пустые указатели }

begin

FreeMem(P, Size);

P := Nil;

end; { MyFreeMem }

procedure MyExitProc; far;

{ процедура всегда получает вызов при прекращении работы

программы }

begin

ExitProc := PreGraphExitProc; { восстановить исходную

процедуру выхода }

CloseGraph; { очистить динамически распределяемую

область }

end; { MyExitProc }

begin

{ инициализировать программу очистки памяти }

PreGraphExitProc := ExitProc;

ExitProc := @MyExitProc;

GraphGetMemPtr := @MyGetMem ; { заменить распределение

памяти }

GraphFreeMemPtr := @MyFreeMem ; { заменить освобождение

памяти }

GraphDriver := Detect;

InitGraph(GraphDriver, GraphMode, '');

ErrorCode := GraphResult;

if ErrorCode <> grOk then

begin

Writeln('Графическая ошибка: ' GraphErrorMsg(ErrorCode);

Readln;

Halt(1);

end;

Line(0, 0, GetMaxX, GetMaxY);

OutText(1, 1, 'Нажмите клавишу <Enter>:');

Readln;

end. { UserHeapManegement }

Если целевой платформой является защищенный режим DOS, то

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

щее: вы должны обеспечить, что любой возвращаемый GetMem указа-

тель должен иметь нулевое смещение. Сделать это можно с помощью

функции GlobalAllocPtr:

procedure MyGetMem(var P: Pointer; Size: Word); far;

var

P: Pointer;

bagin

P:= GlobalAllocPtr(HeapAllocFlags, Size);

GetMem(P, 4096);

end; { MyGetMem }

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