Delphi 7 缓冲区指针覆盖有不同的数据

Delphi 7 Buffer Pointer Overlay Has Different Data

我在Delphi7 中定义了一个大缓冲区和指针作为一个字节数组。 这是 Win32 ReadEventLog 调用的缓冲区。

我定义了第二个指针作为缓冲区数据的记录结构。 这是向字节数组添加结构的叠加层。

问题:两个指针的数据不同。 Buffer^ 数据与 RecordPtr^ 数据不同。 两个指针的地址相同。

问题:声明覆盖指针的正确方法是什么?

Type
  TEventRecord = record
    Length       : dword;
    Reserved     : dword;
    RecordNumber : dword;
    end;

  TByteArray = array of byte;

Var
  Buffer : TByteArray;
  RecordPtr : ^TEventRecord = @Buffer;
  MyData : TEventRecord;

begin
  Setlength (Buffer, $FFF0);
  // ReadEventLog....
  // Watch of Buffer^ and RecordPtr^ shows different data
end.

动态数组Buffer: array of byte是指针,所以@Buffer是指向指针的指针

要按字节访问 TEventRecord 的内容,您可以将指针分配给字节数组数据的开头:

type
  PEventRecord = ^TEventRecord;

var
  PEventRecord_Var: PEventRecord;

begin
  PEventRecord_Var := @Buffer[0]; 

你为什么不这样做呢?

Type
  TEventRecord = record
    Length       : dword;
    Reserved     : dword;
    RecordNumber : dword;
    end;

  TEventLog = array of TEventRecord ;

Var
  Buffer : TEventLog;

begin
  Setlength (Buffer, $FFF0);
  // ReadEventLog(@buffer[0],...) 

end.

你可以这样做:

type
  TEventRecord = record
    Length: DWORD;
    Reserved: DWORD;
    RecordNumber: DWORD;
  end;

  TByteArray = array of Byte;

Var
  Buffer: TByteArray;
  RecordPtr: ^TEventRecord = Pointer(Buffer); // Buffer is a pointer
  MyData: TEventRecord;

begin
  SetLength(Buffer, $FFF0); { Assuming that is big enough }
  { ReadEventLog(..., Pointer(Buffer), Length(Buffer), .... }
  { Watch of Buffer and RecordPtr^ shows same data. }
end.

Buffer 是一个指针,它指向一个(大)字节数的第一个。如果要使用此缓冲区让 ReadEventLog 加载到字节数组中,只需将 Buffer 转换为 Pointer 并将其分配给 RecordPtr。

但是...

如果我理解你的话,另一种选择是:

Buffer: array of TEventRecord;
...
SetLength(Buffer, 6000); { 6000 event records! }
if ReadEventLog(..., Pointer(Buffer), Length(Buffer) * SizeOf(Buffer[0]), ...) then ...

现在您可以轻松访问缓冲区中的每个事件记录。为什么要使用字节数组,如果相反,您可以轻松地直接读取事件记录数组?

(上面的内容适用于普通记录,但@BruceGavin 告诉我事件记录的尾部大小可变,所以这行不通)

您可以像这样实现您想要的:

Var
  Buffer : TByteArray;
  RecordPtr : ^TEventRecord absolute Buffer;

这使得两个变量在内存中占用相同的 4 个字节(或 64 位中的 8 个字节)。