在Delphi中定义其他单元的类型

时间:2022-10-07 16:08:52
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?

不会起作用,因为loren-pechtel在这里说问题是A和B对我来说是不同的单位。那么,有没有办法从另一个类中的现有类型定义类型定义?

8 个解决方案

#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.

在某个单元的接口块中定义类型,然后在需要该类型的其他单元中通过uses子句包含该单元。

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

...

When you need to use TMyArray in another unit:

当您需要在另一个单元中使用TMyArray时:

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.

或者,在单元C的接口部分定义您的类型,并在A和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.

Delphi中的数组类型有点奇怪。看起来A和B的类型完全相同,但Delphi并不认为它们是相同的。 “整数的数组[1..4]”出现两次,因此德尔福认为有两种不同的类型。这只是德尔福的一个奇怪之处。我认为大多数其他语言都不会关心。这在实践中不是问题;这有点奇怪。也许这是有充分理由的。谁知道。正如其他人所说,解决方案是定义您自己的类型,您可以将其放入可供其他单位使用的单元中。我刚才提到这个数组类型的问题,因为它可能让你感到困惑。

#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:

另一种方法,有点旧学但仍然有效,是使用ABSOLUTE关键字强制一个的内存覆盖另一个,并使另一个类型兼容。例如,在单位a中,假设您有以下内容:

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

then in unit b, you have the following:

然后在单元b中,您有以下内容:

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:

这样做是创建一个ArrayA类型的变量“InstanceBasA”,它与变量“InstanceB”覆盖相同的内存空间。这允许您执行以下命令:

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:

将数据从variablea移动到variableb的另一种方法是使用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;

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.

但是你应该确保它们实际上都是数组[1..4],否则你将覆盖一些内存。这就是我添加两个断言的原因。

#7


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

在接口之后和实现之前,只需在UnitB中使用UnitA ...... !!!!

#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.

哪个是缺陷?您正在使用SOURCE大小来获取要移动的字节数,而不是DESTINATION大小!如果SizeOf(A)> SizeOf(B)你有缓冲区溢出而你正在覆盖内存。如果你运气好的话,你会得到一个AV,如果你不是一个可利用的漏洞。总是使用目标大小要好得多,虽然这样你最终可以读取内存,如果大小(B)>大小(A),可能会暴露不需要的数据。无论如何,在移动数据时总是检查结构边界 - 一些公司从他们的代码中禁止这样的操作(即memcpy())。

#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.

在某个单元的接口块中定义类型,然后在需要该类型的其他单元中通过uses子句包含该单元。

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

...

When you need to use TMyArray in another unit:

当您需要在另一个单元中使用TMyArray时:

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.

或者,在单元C的接口部分定义您的类型,并在A和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.

Delphi中的数组类型有点奇怪。看起来A和B的类型完全相同,但Delphi并不认为它们是相同的。 “整数的数组[1..4]”出现两次,因此德尔福认为有两种不同的类型。这只是德尔福的一个奇怪之处。我认为大多数其他语言都不会关心。这在实践中不是问题;这有点奇怪。也许这是有充分理由的。谁知道。正如其他人所说,解决方案是定义您自己的类型,您可以将其放入可供其他单位使用的单元中。我刚才提到这个数组类型的问题,因为它可能让你感到困惑。

#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:

另一种方法,有点旧学但仍然有效,是使用ABSOLUTE关键字强制一个的内存覆盖另一个,并使另一个类型兼容。例如,在单位a中,假设您有以下内容:

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

then in unit b, you have the following:

然后在单元b中,您有以下内容:

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:

这样做是创建一个ArrayA类型的变量“InstanceBasA”,它与变量“InstanceB”覆盖相同的内存空间。这允许您执行以下命令:

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:

将数据从variablea移动到variableb的另一种方法是使用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;

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.

但是你应该确保它们实际上都是数组[1..4],否则你将覆盖一些内存。这就是我添加两个断言的原因。

#7


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

在接口之后和实现之前,只需在UnitB中使用UnitA ...... !!!!

#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.

哪个是缺陷?您正在使用SOURCE大小来获取要移动的字节数,而不是DESTINATION大小!如果SizeOf(A)> SizeOf(B)你有缓冲区溢出而你正在覆盖内存。如果你运气好的话,你会得到一个AV,如果你不是一个可利用的漏洞。总是使用目标大小要好得多,虽然这样你最终可以读取内存,如果大小(B)>大小(A),可能会暴露不需要的数据。无论如何,在移动数据时总是检查结构边界 - 一些公司从他们的代码中禁止这样的操作(即memcpy())。