Ошибка компиляции компонента HtmlViewer для Delphi 7

Я пытаюсь скомпилировать компонент HtmlViewer для Delphi 7 ( https://github.com/BerndGabriel/HtmlViewer ). Открыл проект Frameviewer7.dpk под поддиректором пакета

Однако я получаю следующие ошибки компиляции: HtmlBuffer.pas (1611): Требуется тип массива.

Что соответствует следующему коду:

 if FStart.BytePtr[0] = 0 

И FStart определяется как FStart: TBuffPointer;

TBuffPointer = record
    case Integer of
      0: (BytePtr: PByte;);
      1: (WordPtr: PWord;);
      2: (AnsiChr: PAnsiChar;);
      3: (WideChr: PWideChar;);
    end;

Не уверен, что здесь не так. Мой компилятор - Delphi7

delphi,delphi-7,

1

Ответов: 2


4 принят

FStart.BytePtr[0]указывает, что FStart.BytePtrэто массив , а значение этого выражения является первым (0-м) элементом в этом массиве.

Однако на FStart.BytePtrсамом деле это указатель . Но часто вы можете использовать массивы и указатели для достижения той же задачи - либо вы используете массив TSomeType, либо используете указатель на первый элемент в списке TSomeTypeэлементов в памяти .

Я предполагаю, что это то, что происходит здесь. Следовательно, вы хотите получить первый элемент списка byteзначений, первый из которых встречается по адресу FStart.BytePtr. Чтобы получить byteв этом месте, вы разыменования указателя с помощью ^: FStart.BytePtr^.

Код, который вы обнаружили, пытается получить доступ к данным с использованием нотации массива на указателе. Этот синтаксический сахар может работать в некоторой новой версии или Delphi или с использованием некоторой опции компилятора. (Я не помню).


1

Этот синтаксис использует функцию более поздних компиляторов Delphi, которая позволяет использовать индексированные ссылки для смещений от типизированных указателей. В некоторых версиях Delphi для этого требуется указать параметр или директив компилятора POINTERMATH .

К сожалению, это не поддерживается в Delphi 7.

Типичным способом работы с этим является использование типа массива и объявление указателя на этот тип массива. Фактические границы типа массива не важны (в том смысле, что вы будете использовать тип указателя, чтобы не создавать реальные массивы больших массивов, а обрабатывать указатели, как если бы они были ссылками на такие структуры).

Единственное соображение состоит в том, что верхний предел должен быть выше или равен наивысшему индексу, который вам потребуется указать, чтобы держать компилятор счастливым в том, что любые указанные буквальные индексы могут быть действительными.

т.е. если вы указали массив из 100 единиц, то любой код, который пытался ссылаться на 101-й элемент, не смог бы проверить границы во время компиляции или времени выполнения (если проверка времени выполнения включена).

Итак, для простого примера мы будем использовать массив из 65535 элементов:

const
  MAX_BYTEARRAYDIM = 65535;

type
  TByteArray = array[0..MAX_BYTEARRAYDIM] of Byte;
  PByteArray = ^TByteArray;


procedure SomeExampleMethod;
var
  pb: PByteArray;
begin
  // ..

  pb[12] := 25;  // The array type is 0 based so this sets the value of byte offset 12 bytes from the address in pb
end;

Это имеет преимущество (если это будет проблемой в вашем коде) быть переносимым для всех версий Delphi.

Заявление в вашем случае

В вашем конкретном случае вы могли бы переопределить тип BytePtr таким образом. Не знакомый с кодом HTMLViewer, я не могу сказать, может ли это быть практичным.

Альтернативой могло бы быть объявление необходимых типов массива и указателей, а также приведение типов в зависимости от того, где это необходимо, например:

if PByteArray(FStart.BytePtr)[0] = 0

Конечно, тот же метод может быть применен к другим типам указателей по мере необходимости.

Дельфи, Дельфи-7,
Похожие вопросы