Определение типов из других модулей в Delphi - PullRequest
2 голосов
/ 04 апреля 2009
Var
     A : Array [1..4] of Integer;
     B : Array [1..4] of Integer;

Begin
    A := B;

Не сработает, как сказала Лорен-Печтель здесь проблема А и Б для меня в разных единицах. Итак, есть ли способ определить определение типа из существующего в другом классе?

Ответы [ 8 ]

13 голосов
/ 04 апреля 2009

Определите тип в блоке интерфейса некоторого устройства, а затем включите этот модуль с помощью предложения uses в другие устройства, где вам нужен этот тип.

unit A;
interface
type
  TMyArray = array [1..4] of Integer;

...

Когда вам нужно использовать TMyArray в другом устройстве:

unit B;
interface
uses A;

...
var x : TMyArray;
5 голосов
/ 04 апреля 2009

В качестве альтернативы, определите свой тип в разделе интерфейса блока C и используйте этот блок как в A, так и в B.

1 голос
/ 14 апреля 2009

Другой подход, немного устаревший, но все еще работающий, состоит в том, чтобы использовать ключевое слово 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;
1 голос
/ 04 апреля 2009

Типы массивов в Delphi немного странные. Это выглядит как A и B одного типа, но Delphi не считает, что они одинаковы. «Массив [1..4] of Integer» появляется дважды, поэтому Delphi считает, что есть два разных типа. Это просто странность Delphi. Я думаю, что большинству других языков было бы все равно. На практике это не проблема; это просто немного странно. Может быть, для этого есть веская причина. Кто знает. Решение, как сказали другие, состоит в том, чтобы определить свой собственный тип, который вы можете поместить в модуль, который может использоваться другими модулями. Я только что упомянул эту проблему типов массивов, потому что это может сбить вас с толку.

0 голосов
/ 21 августа 2009

Никогда, никогда, НИКОГДА не используйте код, подобный этому:

// 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 ()) в своем коде.

0 голосов
/ 28 апреля 2009

Просто используйте UnitA в UnitB после inteface и до реализации ... !!!!

0 голосов
/ 14 апреля 2009

Вы можете заставить компилятор предположить, что они принадлежат к одному и тому же типу, задав их тип:

type
  TIntArray = array[1..4] of integer;

begin
  Assert(SizeOf(ArrayA) = SizeOf(TIntArray));
  Assert(SizeOf(ArrayB) = SizeOf(TIntArray));
  TIntArray(ArrayA) := TIntArray(ArrayB);

Но вы должны убедиться, что оба на самом деле являются массивом [1..4], иначе вы перезапишете часть памяти. Вот почему я добавил два утверждения.

0 голосов
/ 14 апреля 2009

Еще один способ перемещения данных из переменной 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;

Это работает благодаря тому факту, что массив расположен линейно, поэтому вы копируете байты, начиная с первой позиции массива, для длины массива.

...