Идёт загрузка страницы...

htp://aptem.net.ru





Delphi 1

Массив констант во время выполнения приложения

...хорошо, непосредственно это синтаксис не поддерживает, поскольку массив констант Array of Const подобен открытым массивам, главным образом в части характеристик времени компиляции. Но вы можете обойти этот неприятный момент, обладая хотя бы начальными знаниями того, как реализован открытый массив. Что нам для этого необходимо: динамически размещенный массив array of TVarRec, который "принимает" ваши параметры, и "псевдоним" (alias) функции Format, позволяющий работать с таким массивом без "ругани" со стороны компилятора.


   
Type
{ объявляем тип для динамического массива array of TVarRecs }
TVarArray = Array [0..High(Word) div Sizeof(TVarRec)-1] of TVarRec;
PVarArray = ^TVarArray;

{ Объявляем alias-тип для функции Format. Передаваемые параметры будут иметь в стеке тот же самый порядок вызова, что и при нормальном вызове Format }
FormatProxy = Function( Const aFormatStr: String; Var aVarRec: TVarRec; highIndex: Integer ): String;

{ AddVarRecs копирует параметры, передаваемые в массиве A в pRecs^, начиная с pRecs^[atIndex]. highIndex - самый большой доступный индекс pRecs, число распределенных элементов - 1. }
Procedure AddVarRecs( pRecs: PVarArray; atIndex, highIndex: Integer; Const A: Array of Const );
Var
i: Integer;
Begin
If pRecs <> Nil Then
For i := 0  To High(A) Do Begin
If atIndex <= highIndex Then Begin
pRecs^[atIndex] := A[i];
Inc(atIndex);
End { If }
Else
Break;
End; { For }
End; { AddVarRecs }

procedure TScratchMain.SpeedButton2Click(Sender: TObject);
Var
p: PVarArray;
S: String;
Proxy: FormatProxy;
begin
{ распределяем массив для четырех параметров, индексы - 0..3 }
GetMem(p, 4*Sizeof(TVarRec));
try
{ добавляем параметры последующими вызовами AddVarRecs }
AddVarRecs( p, 0, 3, [12, 0.5, 'Шаблон']);
AddVarRecs( p, 3, 3, ['Тест'] );

{ получаем полномочия Format }
@Proxy := @SysUtils.Format;

{ Вызов с динамически сгенерированным массивом параметров. Естественно, строка формата может также быть сформирована и во время выполнения программы. }
S := Proxy('Целое: %d, Реальное: %4.2f, Строки: %s, %s', p^[0], 3 );

{ выводим результат }
ShowMessage(S);
finally
FreeMem( p,4*Sizeof(TVarRec));
end;
end;

Я надеюсь вы поняли принцип. Естественно, имеются ограничения. Вы можете передавать в AddVarRecs числовые величины, строковые переменные и литералы, но не в коем случае не строковые выражения! В этом случае компилятор должен для хранения результата сформировать в стеке временную строку, передать ее в AddVarRecs (или лучше по адресу в TVarRec), и она может прекратить свое существование или может быть перезаписана в стеке другими данными, если в конечном счете вы передадите в Proxy целый массив!

Тестировалось только в Delphi 1.0!

- Peter Below [000955]