Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Массив констант во время выполнения приложения

Автор: Peter Below

...хорошо, непосредственно это синтаксис не поддерживает, поскольку массив констант 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!

Проект Delphi World © Выпуск 2002 - 2024
Автор проекта: USU Software
Вы можете выкупить этот проект.