gpt4 book ai didi

string - 在 Delphi XE4 中使用 AnsiString 之类的数组字节

转载 作者:行者123 更新时间:2023-12-03 19:08:02 24 4
gpt4 key购买 nike

试图移动Delphi 2007项目至XE4 .在 Delphi 2007我正在使用从套接字读取字节数组的函数 Indy直接地。我通过了AnsiString转换为字节数组到此函数的 var 参数:

var data:AnsiString;
AContext.Connection.IOHandler.ReadBytes(TIDBytes(Data), PacketLength-PacketLengthDelta-1, False);

Dlphi XE当我尝试连接 Data到我得到的另一个字符串 access violation错误。

现在我试图用更简单的代码来模拟这个问题:
TIdBytes = array of Byte;

procedure fill(var b: TIDBytes);
begin
setlength(b,5);
b[0]:=61;
b[1]:=61;
b[2]:=61;
b[3]:=61;
b[4]:=61;

//original function used move function
end;



procedure TMainForm.FormCreate(Sender: TObject);
var s: ansistring ;
begin
fill( TIDBytes(s) );
Showmessage(s);
end;

现在我希望看到像 ==== 这样的东西在消息框中,但我得到了一个空的。我认为 XE AnsiString 的行为与 Delphi 2007 Ansistring 相同,您可以在这两种情况下像字节数组一样使用它们。

解决用字节填充 AnsiString 问题的最佳方法是什么?

最佳答案

施放 AnsiString 永远无效到一个字节数组。该代码总是被破坏并且您很幸运(或不幸,取决于您的观点)。

托管字符串类型,就像动态数组一样,有一个额外的信息负载,即元数据,它存储在数据负载之前。此元数据包括引用计数、长度等。但字符串的元数据与动态数组的元数据不同。简单地说,字符串不是动态数组。您的重新解释类型转换完全无效。它在旧版本的 Delphi 中无效,在现代版本中同样无效。

真正发生在幕后的是元数据的大小随着 Unicode 支持的引入而发生了变化。 AnsiString 的元数据已扩大。例如,它现在包含字符串的代码页。

现在,当您调用 SetLength ,分配足够大的内存块用于元数据和有效负载。假设内存分配在地址 P。变量(字符串或动态数组)保存的地址设置为 P + 元数据大小。当您开始释放对象时,系统将移动到 P - 元数据大小并调用 FreeMem与那个地址。这是踢球者。分配时使用动态数组元数据的大小,但释放时使用字符串元数据的大小。结果?繁荣!您刚刚调用了FreeMem在一个无效的地址上,一个尚未分配给您的地址。

处理这个问题的正确方法是给 Indy 函数它想要的东西。即一个字节数组。如果您需要传输到字符串变量,请将字节数组的内容复制到新字符串中。例如使用 TEncoding.Default.GetString() .

关于string - 在 Delphi XE4 中使用 AnsiString 之类的数组字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20611507/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com