Определение типов из других единиц в Delphi
-
23-08-2019 - |
Вопрос
Var
A : Array [1..4] of Integer;
B : Array [1..4] of Integer;
Begin
A := B;
Не будет работать, как сказал Лорен-Пехтель здесьПроблема в том, что A и B для меня в разных подразделениях. Итак, есть ли способ определить определение типа из существующего в другом классе?
Решение
Определите тип интерфейсного блока некоторых блоков, а затем включите этот блок через uses
пункт в других подразделениях, где вам нужен этот тип.
unit A;
interface
type
TMyArray = array [1..4] of Integer;
...
Когда вам нужно использовать TMyArray
в другом блоке:
unit B;
interface
uses A;
...
var x : TMyArray;
Другие советы
В качестве альтернативы определите свой тип в разделе интерфейса блока C и используйте этот блок как в A, так и в B.
Типы массива в Delphi немного странные. Это внешний вид Как A и B имеют точно такой же тип, но Delphi не считает, что они одинаковы. «Массив [1..4] целого числа» появляется дважды, поэтому Дельфи думает, что есть два разных типа. Это просто странность Дельфи. Я думаю, что большинство других языков будут все равно. Это не проблема на практике; Это просто странно. Может быть, есть веская причина. Кто знает. Решение, как говорили другие, определяет ваш собственный тип, который вы можете поместить в устройство, которое можно использовать другими подразделениями. Я просто упоминаю эту проблему типов массива, потому что это может сбить вас с толку.
Другой подход, немного старая школа, но все еще работает, - использовать абсолютное ключевое слово, чтобы заставить память одного для наложения другого и сделать другой тип совместимым. Например, в блоке A, скажем, у вас есть следующее:
TYPE
TArrayA = Array[1..4] of integer;
Затем в блоке B у вас есть следующее:
TYPE
TArrayB = Array[1..4] of integer;
Для совместимости вы можете сделать следующее:
VAR
InstanceA : TArrayA;
InstanceB : TArrayB;
InstanceBasA : TArrayA ABSOLUTE InstanceB;
Это создает переменную «ancessbasa» абортов типа, которая накладывает одно и то же пространство памяти, что и переменная «экземпляры». Это позволяет вам выполнить следующую команду:
InstanceA := InstanceBasA;
Еще один метод перемещения данных из variablea в variableb - это использование команды перемещения. Например, чтобы перейти из Арреи в ArrayB, вы можете сделать следующее:
var
ArrayA : array[1..4] of Integer;
ArrayB : Array[1..4] of Integer;
begin
FillChar(ArrayB[1],SizeOf(ArrayB),#0);
ArrayA[1] := 1234;
ArrayA[2] := 3456;
ArrayA[3] := 7890;
ArrayA[4] := 9876;
// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );
Assert( ArrayA[4] = ArrayB[4], 'ArrayA[4] <> ArrayB[4]');
end;
Это работает тем фактом, что массив проложен линейным образом, поэтому вы копируете байты, начинающиеся в первом положении массива, для длины массива.
Вы можете заставить компилятора предположить, что они такого же типа, типизируя их:
type
TIntArray = array[1..4] of integer;
begin
Assert(SizeOf(ArrayA) = SizeOf(TIntArray));
Assert(SizeOf(ArrayB) = SizeOf(TIntArray));
TIntArray(ArrayA) := TIntArray(ArrayB);
Но вы должны убедиться, что оба на самом деле являются массивами [1..4] в противном случае, вы перезаписываете некоторую память. Вот почему я добавил два утверждения.
Просто используйте Unita в Unitb после Inteface и до реализация ...!!!!
Никогда, никогда, никогда не используйте код таким:
// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );
Где недостаток? Вы используете размер источника, чтобы получить количество байтов для перемещения, а не размер назначения !!! Если sizeof (a)> sizeof (b) у вас есть переполнение буфера, и вы перезаписываете память. Если вам повезет, вы получаете AV, если вы не имеете уязвимости. Гораздо лучше всегда использовать размер назначения, хотя таким образом вы можете в конечном итоге читать память, если не следует, если размер (b)> размер (а), возможно, разоблачение нежелательных данных. В любом случае, всегда проверяйте границы структуры при перемещении данных - некоторые компании запрещали такие операции, как это (т.е. memcpy ()) из их кода.