我有一个TBytes
数组,我希望像DWORD
数组一样访问它,但我不想制作TBytes
数组的新副本。我试图对它进行类型转换,但新变量的长度与旧变量的长度相同,而不是Length(TBytes)/4
。如果我想设置正确的长度,Delphi会复制它,两个数组之间的连接就会丢失。它可以使它工作吗?
答案 0 :(得分:3)
您需要获取指向数组数据的指针,然后键入它。简单地键入指针并不会改变你仍然指向一个字节数组的事实,这就是为什么长度是相同的。您必须通过将数组长度除以4来手动计算DWORD
的数量。
试试这个:
var
bytes: TBytes;
values, value: LPDWORD;
i, numValues: Integer;
begin
// populate bytes as needed...
values := LPDWORD(bytes);
value := values;
numValues := Length(bytes) div sizeof(DWORD);
for I := 0 to numValues-1 do
begin
// use value^ as needed...
Inc(value);
end;
end;
或者,如果您使用的是Delphi 2009 +:
{$POINTERMATH ON}
var
bytes: TBytes;
values: LPDWORD;
i, numValues: Integer;
begin
// populate bytes as needed...
values := LPDWORD(bytes);
numValues := Length(bytes) div sizeof(DWORD);
for I := 0 to numValues-1 do
begin
// use values[i] as needed...
end;
end;
答案 1 :(得分:0)
您可以定义其他类型:
TIEEE754Float = record
case Boolean of // Access to the same memory area
True:
(Byte1, Byte2, Byte3, Byte4: Byte); // As 4 bytes
False:
(Float: Single); // As 32-bit float
end;
我正在使用它进行MODBUS通讯
procedure TestTModbusRtu.TestWriteFrame;
const
KS_45_ADDRESS = 2;
DEVICE_ADDRESS = KS_45_ADDRESS;
FUNCTION_CODE = TFunctionCode.fcWriteMultipleRegisters;
MEMORY_ADDRESS = 16472; // Set target temperature
EXPECTED_VALUE = 45.5;
var
frame: TFrame;
value: TIEEE754Float;
begin
frame.DeviceAddress := DEVICE_ADDRESS;
frame.FunctionCode := FUNCTION_CODE;
frame.DataArray[0] := MEMORY_ADDRESS div 256; // Addresse (High Bit)
frame.DataArray[1] := MEMORY_ADDRESS mod 256; // Addresse (Low Bit)
frame.DataArray[2] := 0; // Anzahl des Wertes (High)
frame.DataArray[3] := 2; // Anzahl des Wertes (Low)
frame.DataArray[4] := 4; // Anzahl des Bytes geschickt
value.Float := EXPECTED_VALUE;
frame.DataArray[5] := value.Byte4;
frame.DataArray[6] := value.Byte3;
frame.DataArray[7] := value.Byte2;
frame.DataArray[8] := value.Byte1;
PrepareModbusRtuConnection(fModbusRtu);
fModbusRtu.Connect;
try
fModbusRtu.WriteFrame(frame);
...
finally
fModbusRtu.Disconnect;
end;
end;