TArray <байт> VS TBytes VS PByteArray

Те 3 типа очень похожи...

TArray является универсальной версией TBytes. Оба могут быть литыми к PByteArray и используемые в качестве буфера для вызовов к Windows API. (с теми же ограничениями как строка к Pchar).

Что я хотел бы знать: это поведение "дизайном" или "Реализацией". Или более конкретно, это могло прервать будущий выпуск?

//Редактирование Как указанное ниже... То, что я действительно хочу знать: это столь же безопасное преобразовать тип TBytes (или TArray) к PByteArray, как он должен преобразовать тип Строки к PChar, что касается прямой совместимости. (Или возможно AnsiString к PAnsiChar является лучшим exemple ^_^),

5
задан Ken Bourassa 11 March 2010 в 19:26
поделиться

2 ответа

Проще говоря, массив байтов - это массив байтов, и пока определения байта и массива не изменяются, это тоже не изменится. Вы можете безопасно использовать его таким образом, если убедитесь, что соблюдаете границы массива, поскольку приведение его из типов массивов Delphi обнуляет вашу проверку границ.

РЕДАКТИРОВАТЬ: Думаю, теперь я немного лучше понимаю, о чем вы спрашиваете.

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

Однако вы можете преобразовать указатель на элемент 0 динамического массива в указатель на массив в стиле C. Этот будет работать и не изменится.

3
ответ дан 14 December 2019 в 19:10
поделиться

Два из этих типов похожи (фактически идентичны). Третий - нет.

TArray объявлен как "Array of Byte", как и TBytes. Однако вы пропустили еще один очень важный тип, TByteArray (тип, на который ссылается PByteArray).

Будучи указателем на TByteArray, PByteArray, строго говоря, является указателем на статический байтовый массив, а не на динамический массив (каковыми являются все остальные типы байтовых массивов). Он типизирован таким образом для того, чтобы можно было ссылаться на смещения от этого базового указателя, используя целочисленный индекс. Обратите внимание, что эта индексация ограничена 2^15 элементами (0..32767). Для произвольных байтовых смещений (> 32767) от некоторого базового указателя, PByteArray не годится:

var
  b: Byte;
  ab: TArray<Byte>;
  pba: PByteArray;
begin
  SetLength(ab, 100000);
  pba := @ab;             // << No cast necessary - the compiler knows (magic!)
  b   := pba[62767];      // << COMPILE ERROR!
end;

т.е. приведение Array of Byte или TArray к PByteArray потенциально приведет к проблемам, когда массив имеет > 32K элементов (и указатель передается в код, который пытается получить доступ ко всем элементам). Приведение к нетипизированному указателю, конечно, позволяет избежать этого (при условии, что "получатель" указателя затем обрабатывает доступ к памяти, на которую ссылается указатель, соответствующим образом).

НО, все это вряд ли изменится в будущем, это просто следствие деталей реализации, которые уже давно применяются в этой области. Введение синтаксически подкрепленного объявления общих типов - это kipper rouge.

2
ответ дан 14 December 2019 в 19:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: