delphi - 为什么在使用 readbuffer 时使用 string[1] 而不是 string

标签 delphi delphi-2007 delphi-2006

我有这样的记录

  TEmf_SrectchDIBits = packed record
    rEMF_STRETCHDI_BITS: TEMRStretchDIBits;
    rBitmapInfo: TBitmapInfo;
    ImageSource: string;
  end;
  ---
  ---
  RecordData: TEmf_SrectchDIBits;

如果我像这样使用 TStream 将数据读入其中,则会发生异常

SetLength(RecordData.ImageSource, pRecordSize);

EMFStream.ReadBuffer(RecordData.ImageSource,pRecordSize) 

但是如果我使用下面的代码,它可以正常工作

SetLength(RecordData.ImageSource, pRecordSize);

EMFStream.ReadBuffer(RecordData.ImageSource[1], pRecordSize);

那么使用 String 和 String[1] 之间的区别是什么

最佳答案

差异在于与 .ReadBuffer 方法签名相关的细节。

签名是:

procedure ReadBuffer(var Buffer; Count: Longint);

如您所见,Buffer 参数没有类型。在本例中,您是说您想要访问基础变量。

但是,字符串是两部分,一个指针(变量的内容)和字符串(变量指向这个)。

因此,如果仅给定 ReadBuffer 字符串变量,则它将有 4 个字节用于将数据存储到字符串变量中,并且效果不会很好,因为字符串变量应该保存一个指针,而不仅仅是任何指针随机二进制数据。如果 ReadBuffer 写入超过 4 个字节,它将用新数据覆盖内存中的其他内容,这可能是灾难性的操作。

通过将 [1] 字符传递给 var 参数,您可以让 ReadBuffer 访问字符串变量指向的数据,这正是您想要的。毕竟您想要更改字符串内容

此外,请确保您已将字符串变量的长度设置得足够大,可以容纳您正在读取的任何内容。

另外,最后一点,我无法验证。在旧的 Delphi 版本中,字符串变量包含 1 字节字符。在较新的版本中,我认为由于 unicode,它们是两个,因此代码可能无法在较新版本的 Delphi 中按预期工作。您可能想改用字节数组或堆内存。

关于delphi - 为什么在使用 readbuffer 时使用 string[1] 而不是 string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3192760/

相关文章:

mysql - 使用 SQL 参数保护我的应用程序免受注入(inject)攻击

delphi - TDirect2DCanvas 中的字体方向不起作用?

delphi - TDataSet 和 TClientDataset 内存管理有什么区别?

delphi - 如何以简单安全的方式扩展 TFieldDef?

delphi - 在Delphi中查找 "non-leak"内存使用问题的策略或工具?

file - 该系统找不到指定的文件

delphi - 失去焦点时保持 InPlaceEditor 突出显示

Delphi 2007 x Windows 10 - 打开项目时出错

delphi - 如何在Delphis MessageDlg中忽略计时器事件

database - 使用 Delphi 2010 从 BLOB 加载时出现 Jpeg 错误 #51,在 Delphi 2006 中正常