试图移动Delphi 2007
项目XE4
。 在Delphi 2007
我用函数读取使用从插座字节数组Indy
直接。 我通过AnsiString
强制转换为字节给这个函数的变量参数数组:
var data:AnsiString;
AContext.Connection.IOHandler.ReadBytes(TIDBytes(Data), PacketLength-PacketLengthDelta-1, False);
在Dlphi XE
当我尝试concatinate 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类型就像2007年德尔福AnsiString类型相同,你可以使用他们喜欢在这两种情况下字节数组。
什么是解决问题的字节填充AnsiString类型的最好方法?
这是从来没有有效投的AnsiString
为一个字节数组。 该代码(这取决于你的观点或倒霉的)总是坏,你真的很幸运。
管理字符串类型,就像动态数组,具有信息,元数据,即刚好在数据有效载荷之前存储的额外的有效载荷。 该元数据包括参考计数,长度等,但字符串中的元数据是不一样的,作为动态数组。 简单地说,一个字符串是不是一个动态数组。 您重新解释投是完全无效的。 这是在旧版本的Delphi无效的,它只是在现代版本为无效。
到底发生了什么引擎盖下是元数据的规模已经引进的Unicode支持改变。 对于元数据AnsiString
已经扩大。 现在,它包含,例如,字符串的代码页。
现在,当你调用SetLength
,内存足够大的元数据和有效载荷的块被分配。 假设存储器在地址P分配,你的变量(字符串或动态数组)持有被设置为P +元数据尺寸的地址。 当你来到解除分配对象,系统运行至P -元数据的大小,并调用FreeMem
与该地址。 而这里的起脚。 如果取消分配可以使用,当你分配一个动态数组元数据的大小,而是一个字符串的大小元数据。 结果? 繁荣! 你刚才叫FreeMem
上一个无效的地址,尚未分配给你一个。
以正确的操作方法是给印地功能它想要的东西。 即一个字节数组。 如果您需要转移到一个字符串变量,字节数组的内容复制到一个新的字符串。 例如使用TEncoding.Default.GetString()
使用您的填充过程和你的TIDBytes定义:
procedure Test;
var
s: ansistring;
b: TIDBytes;
begin
fill(b);
s := StringOf(TArray<byte>(b));
ShowMessage(s);
end;
PS:@大卫的答案是正确的,但你可以使用directy的字节数组,然后使用StringOf得到串/ AnsiString类型