问题
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?
回答1:
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;
回答2:
Alternatively, define your type in the interface section of unit C and use this unit in both A and B.
回答3:
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.
回答4:
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;
回答5:
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.
回答6:
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.
回答7:
Just use UnitA in UnitB after inteface and before the implementation ...!!!!
回答8:
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.
来源:https://stackoverflow.com/questions/715572/defining-types-from-other-units-in-delphi