我有一个数据结构:
data = array of integer;
我已经从
填充了它source = array of byte;
与
data[x] := Source[offset] or (Source[offset + 1] shl 8) or
(Source[offset + 2] shl 16) or (Source[offset + 3] shl 24);
处理完这些块后,我必须将它们带回“字节”......
任何想法?
答案 0 :(得分:7)
您可以使用Move。
在单行中执行此操作Move(source[0], dest[0], Length(source)*SizeOf(source[0]));
如果需要执行网络/主机字节顺序转换,则可以在Move
之后运行整数数组。
在相反的方向上你反过来。
如果您没有字节顺序问题,那么您可能根本不需要转换为字节数组。您可以按原样使用整数数组。请记住,没有字节顺序问题,字节和整数数组的内存布局是相同的(这就是为什么你能够用Move
进行blit。)
答案 1 :(得分:6)
你的意思是这样吗?
var
i: integer;
b1, b2, b3, b4: byte;
begin
b1 := byte(i);
b2 := byte(i shr 8);
b3 := byte(i shr 16);
b4 := byte(i shr 24);
尝试,例如,
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
b1, b2, b3, b4: byte;
begin
i := $AABBCCDD;
b1 := byte(i);
b2 := byte(i shr 8);
b3 := byte(i shr 16);
b4 := byte(i shr 24);
ShowMessage(IntToHex(b1, 2));
ShowMessage(IntToHex(b2, 2));
ShowMessage(IntToHex(b3, 2));
ShowMessage(IntToHex(b4, 2));
end;
答案 2 :(得分:6)
嗯......我看到一个使用Move的答案,一个使用轮班,但是一个简单的演员怎么样?:
var
I: Integer;
B: array[0..3] of Byte;
begin
// from bytes to integer:
I := PInteger(@B)^;
// from integer to bytes:
PInteger(@B)^ := I;
或使用您的阵列:
data[i] := PInteger(@source[offset])^;
反之亦然:
// get low byte
source[offset] := PByte(@data[i])^; // or := PByte(@data[i])[0];
// get second byte
secondByte := PByte(@data[i])[1]; // or := (PByte(@data[i]) + 1)^;
或
PInteger(@source[offset])^ := data[i];
如您所见,通过强制转换指针可以获得很长的路要走。这实际上并不占用指针,编译器足够聪明,可以直接访问项目。
答案 3 :(得分:0)
如评论所示,您无需移动数据即可以字节和整数形式访问它。
您的原始字节数组可以按类型转换的整数数组进行访问。
type
TArrayInteger = array of Integer;
...
for i := 0 to Pred(Length(source)) div SizeOf(Integer) do
WriteLn(TArrayInteger(source)[i]);
通常我会在类中隐藏这些类型转换。在XE3中,有可能为简单类型声明类助手,如字符串,字节,整数等。例如,请参阅TStringHelper。 对于简单类型的数组也是如此。
以下是使用记录助手的示例:
type
TArrayByte = array of Byte;
TArrayInteger = array of Integer;
TArrayByteHelper = record helper for TArrayByte
private
function GetInteger(index : Integer) : Integer;
procedure SetInteger(index : Integer; value : Integer);
public
property AsInteger[index : Integer] : Integer read GetInteger write SetInteger;
end;
function TArrayByteHelper.GetInteger(index: Integer): Integer;
begin
Result := TArrayInteger(Self)[index];
end;
procedure TArrayByteHelper.SetInteger(index: Integer; value: Integer);
begin
TArrayInteger(Self)[index] := value;
end;
像这样使用:
Var
source : TArrayByte;
i : Integer;
begin
SetLength(source,8);
for i := 0 to 7 do
source[i] := i;
for i := 0 to 1 do
WriteLn(Format('%8.8X',[source.AsInteger[i]]));
ReadLn;
end.
答案 4 :(得分:0)
要将其构建为功能:
Type TBytes = array of byte;
function InttoBytes(const int: Integer): TBytes;
begin
result[0]:= int and $FF;
result[1]:= (int shr 8) and $FF;
result[2]:= (int shr 16) and $FF;
end;