如果我为64位Windows编译,我的Byte-Arrays没有正确的输入值。 如果我为x32-Windows编译此过程,则值是正确的。
任何人都可以帮助我吗?
procedure doAnything(AText: String); //for example "<xml><s name="hello"/></xml>"
var
myArray:array of Byte absolute AText;
begin
... (* myArray for x32: correct Length and Values (60, 0, 120, 0, 109, 0, ...) *)
... (* myArray for x64: Length: 2 (60, 0) *)
end
答案 0 :(得分:7)
字符串的内存布局与动态数组不同。
在这里使用absolute
关键字是完全错误的。
在32位中,恰好读取了长度,但值是字符,而不是字节。
您可以执行以下操作以字符串形式访问字符串:
procedure doAnything(AText: String); //for example "<xml><s name="hello"/></xml>"
var
pB : PByte;
i,len : Integer;
begin
pB := Pointer(AText);
len := Length(AText)*SizeOf(Char);
for i := 1 to len do
begin
WriteLn(pB^);
Inc(pB);
end;
// Or
for i := 0 to len-1 do
begin
WriteLn(pB[i]);
end;
end;
答案 1 :(得分:4)
如果要将String
的字符数据作为原始字节访问,则必须使用类型转换,不要使用absolute
作为内存正如其他人向您指出的那样,String
和动态数组的布局不兼容:
procedure doAnything(AText: String);
var
myBytes: PByte;
myBytesLen: Integer;
begin
myBytes := PByte(PChar(AText));
myBytesLen := ByteLength(AText);
// or: myBytesLen := Length(AText) * SizeOf(Char);
// use myBytes up to myBytesLen as needed...
end;
如果您真的想使用absolute
,则必须使用它更像这样:
procedure doAnything(AText: String);
var
myChars: PChar;
myBytes: PByte absolute myChars;
myBytesLen: Integer;
begin
myChars := PChar(AText);
myBytesLen := ByteLength(AText);
// or: myBytesLen := Length(AText) * SizeOf(Char);
// use myBytes up to myBytesLen as needed...
end;
答案 2 :(得分:3)
根据我的理解,问题是你在64位世界中映射苹果和梨。如果你看一下:
http://docwiki.embarcadero.com/RADStudio/XE5/en/Internal_Data_Formats#Dynamic_Array_Types
字符串:
http://docwiki.embarcadero.com/RADStudio/XE5/en/Internal_Data_Formats#Long_String_Types
您将看到这两个长度具有不同的字节数。抵消也不匹配。基本上他们不兼容。