Определение типов из других модулей в Delphi
Var
A : Array [1..4] of Integer;
B : Array [1..4] of Integer;
Begin
A := B;
Не сработает, как сказала здесь Лорен-Печтель, проблема в том, что А и Б для меня в разных подразделениях. Итак, есть ли способ определить определение типа из существующего в другом классе?
8 ответов
Определите тип в интерфейсном блоке некоторого устройства, а затем включите его через 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] of Integer" появляется дважды, поэтому Delphi считает, что есть два разных типа. Это просто странность Delphi. Большинство других языков, я думаю, не заботятся. На практике это не проблема; это просто немного странно. Может быть, для этого есть веская причина. Кто знает. Решение, как сказали другие, состоит в том, чтобы определить свой собственный тип, который вы можете поместить в модуль, который может использоваться другими модулями. Я просто упомянул эту проблему типов массивов, потому что это может сбить вас с толку.
Другой подход, немного устаревший, но все еще работающий, состоит в том, чтобы использовать ключевое слово ABSOLUTE, чтобы заставить один из них перекрывать другой и сделать совместимым другой тип. Например, в блоке а, скажем, у вас есть следующее:
TYPE
TArrayA = Array[1..4] of integer;
тогда в блоке b у вас есть следующее:
TYPE
TArrayB = Array[1..4] of integer;
Для совместимости вы можете сделать следующее:
VAR
InstanceA : TArrayA;
InstanceB : TArrayB;
InstanceBasA : TArrayA ABSOLUTE InstanceB;
Это создает переменную "InstanceBasA" типа ArrayA, которая перекрывает то же пространство памяти, что и переменная "InstanceB". Это позволяет вам выполнить следующую команду:
InstanceA := InstanceBasA;
Никогда, никогда, НИКОГДА не используйте код, подобный этому:
// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );
Где недостаток? Вы используете размер SOURCE, чтобы получить количество байтов для перемещения, а не размер DESTINATION!!! Если SizeOf(A) > SizeOf(B), у вас переполнение буфера и вы перезаписываете память. Если вам повезет, вы получите AV, если нет, у вас есть уязвимость, которую можно использовать. Намного лучше всегда использовать конечный размер, хотя в этом случае вы можете в конечном итоге читать память, а не делать это, если Размер (B) > Размер (A), возможно, отображает нежелательные данные. В любом случае, всегда проверяйте границы структуры при перемещении данных - некоторые компании запретили такие операции (например, memcpy()) в своем коде.
Еще один метод перемещения данных из переменной a в переменную b - это использование команды MOVE. Например, чтобы перейти от ArrayA к 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 и перед реализацией...!!!!