将指针转换为 TBytes

Convert a Pointer to TBytes

我有这个代码:

procedure  MyFunct(const aBin; aBinSize : Cardinal);
var bytes: Tbytes;
begin
  bytes := Tbytes(@aBin);
  for var I := 0 to aBinSize - 1 do
    writeln(bytes[i]);
end;      

var Memory: Pointer
...init the memory...
MyFunct(Memory^, sizeOfMemory);

这几年在 {$R-}(范围检查)方面工作得很好。但是今天我决定停用 {$R-} 现在下面的代码因范围检查错误而崩溃,当是时正常,因为我 length(bytes) 它通常等于 0.

所以我可以重新激活 {$R-} 但现在我认为这是一个根本错误,因为据我所知,一个 Tbyte 的长度存储在字节 [-32bit] 中,最重要的是引用计数Tbytes 存储在 bytes[-64bit]。所以现在我担心之前的代码只是简单地以字节[-64位]写入引用计数并破坏我的记忆(可能不确定)。

这样做是个好习惯吗

bytes := Tbytes(@aBin);

如果不是为什么编译器会授权它?在没有 Tbytes 的情况下,我如何浏览我内存的每个字节(即如何访问 myMemory[x])

您不能像现在这样将任意指针强制转换为 TBytes,它们是完全不同的东西。如果指向的内存不是有效的动态数组,则代码将失败。你的代码多年来一直有问题,你很幸运它什么都没做。

当您按原样使用 TBytes 时,该函数需要看起来更像这样:

procedure MyFunct(const aBin; aBinSize : Cardinal);
var bytes: TBytes;
begin
  SetLength(bytes, aBinSize);
  Move(aBin, bytes[0], aBinSize);
  for var I := 0 to aBinSize - 1 do
    WriteLn(bytes[i]);
end;      

否则,更简单的方法(这可能是您尝试做的)会更像这样:

procedure MyFunct(const aBin; aBinSize : Cardinal);
var bytes: PByte;
begin
  bytes := PByte(@aBin);
  for var I := 0 to aBinSize - 1 do
    WriteLn(bytes[i]);
end;