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 个字节)。
我在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 个字节)。