Pascal 记录在记录中混合字和字节不能按预期工作

Pascal records mixing word and bytes in records doesn't work as expected

我的数据是这样的(一个字节每两个'-'):

+----+--+----+----+
|0840|0C|00AD|0840|
+----+--+----+----+

如果我使用此代码:错误

Type TAlarmasRATP = record
   Funcion   : word;
   Instancia : byte;
   Err_0     : word;
   Err_1     : word;
end;

函数 = 4008,Instancia = 0C,Err_0 = 08AD,Err_1 = 0040

如果我使用此代码:RIGHT

Type TAlarmasRATP = record
   Funcion   : word;
   Instancia : byte;
   Err_0     : array [0..1] of byte;
   Err_1     : array [0..1] of byte;
end;

函数 = 4008,Instancia = 0C,Err_0 = AD00,Err_1 = 4008

为什么第一个不起作用?

使用记录类型时,字段根据规范对齐Internal data formats - Record types:

type alignment in bytes (32bit platform)
ordinal size of the type (i.e. 1 for Byte, 2 for Word, 4 for Cardinal, or 8 for Int64)
real 2 for Real48, 4 for Single, 8 for Double and Extended
ShortString 1
Array Same as the element type of the array
Record The largest alignment of the fields in the record
Set Size of the type (1, 2, or 4), otherwise always 1
all other Determined by the {$A} directive

这意味着:在第一个记录声明中,Err_0 字段将在 Word 边界上对齐,并且会在 Instancia 字段后附加一个填充字节。

在第二个记录声明中,Err_0 字段将在 Byte 边界上对齐,因为它是 Byte 的数组,并且 [= 之后没有填充27=] 字段。由于记录未打包,因此将在结构末尾插入一个填充字节 - 因此在两种情况下记录大小都将四舍五入为 8。

如果您使用 packed 关键字,记录中的所有字段将被打包到字节边界,并且记录的大小将恰好是字段大小的总和,末尾没有填充。

如果记录大小为 7,您只需声明:

type TAlarmasRATP = packed record
   Funcion   : Word;
   Instancia : Byte;
   Err_0     : Word;
   Err_1     : Word;
end;

但是,如果您需要 8 的大小,您应该通过定义另一个您从不使用的字段来在末尾手动添加一个填充字节:

type TAlarmasRATP = packed record
   Funcion   : Word;
   Instancia : Byte;
   Err_0     : Word;
   Err_1     : Word;
   Padding   : Byte;  // Unused
end;