views:

447

answers:

8
Var
     A : Array [1..4] of Integer;
     B : Array [1..4] of Integer;

Begin
    A := B;

Won't work as loren-pechtel said here the problem is A and B for me are in different units. So, is there a way to define a type definition from a existing one in another class?

+10  A: 

Define type in interface block of some unit and then include that unit via uses clause in other units where you need that type.

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

...

When you need to use TMyArray in another unit:

unit B;
interface
uses A;

...
var x : TMyArray;
zendar
+5  A: 

Alternatively, define your type in the interface section of unit C and use this unit in both A and B.

gabr
+1  A: 

Array types in Delphi are a bit odd. It looks like A and B are of exactly the same type, but Delphi doesn't consider that they are the same. "Array [1..4] of Integer" appears twice, so Delphi thinks there are two different types. That's just an oddity of Delphi. Most other languages, I think, wouldn't care. It's not a problem in practice; it's just a bit strange. Maybe there is a good reason for it. Who knows. The solution, as the others have said, is define your own type, which you can put in a unit that can be used by other units. I just mention this issue of array types because it may be confusing you.

dangph
There is a good reason for it--it lets you make types distinct even though they are technically the same. The stronger the typing the more often the compiler catches your mistake rather than having to find it with the debugger.
Loren Pechtel
Not just array types. ALL structured types. You can define two records with the same structure, but they're not the same types. Define two classes with the same structure, and they're not the same, either.
Rob Kennedy
+1  A: 

Another approach, a bit old school but still works, is to use the ABSOLUTE keyword to force the memory of one to overlay another, and make the other type compatible. For example, in unit a lets say you have the following:

TYPE
  TArrayA = Array[1..4] of integer;

then in unit b, you have the following:

TYPE
  TArrayB = Array[1..4] of integer;

For compatibility, you can do the following:

VAR
  InstanceA : TArrayA;
  InstanceB : TArrayB;
  InstanceBasA : TArrayA ABSOLUTE InstanceB;

What this does is create a variable "InstanceBasA" of type ArrayA which overlays the same memory space as the variable "InstanceB". This allows you to do the following command:

InstanceA := InstanceBasA;
skamradt
A: 

One more method of moving data from variablea to variableb is to use the MOVE command. For example, to move from ArrayA to ArrayB you can do the following:

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;

This works by the fact that the array is layed out in a linear fashion, so your copying the bytes starting at the first array position, for the length of the array.

skamradt
A: 

You can force the compiler to assume they are of the same type by typecasting them:

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

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

But you should make sure that both actually are array[1..4] of otherwise you will overwrite some memory. That's why I added the two assertions.

dummzeuch
A: 

Just use UnitA in UnitB after inteface and before the implementation ...!!!!

A: 

Never, never, NEVER use code like this:

// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );

Where's the flaw? You're using the SOURCE size to get the number of bytes to move, not the DESTINATION size!!! If SizeOf(A) > SizeOf(B) you have a buffer overflow and you're overwriting memory. If you're luck you get an AV, if you're not you have an exploitable vulnerability. It's far better to always use the destination size, although this way you can end up reading memory you shouldn't if Size(B) > Size(A), maybe exposing unwanted data. Anyway, always check structure boundaries when moving data - some companies banned operations like this (i.e. memcpy() ) from their code.

ldsandon