我正在尝试在小端机上使用FreePascal来读取和解释集成电路中的数据。数据本质上是由紧密打包(主要是)的大端整数组成,其中一些(实际上很多)未对齐字节边界。因此,我为此尝试使用FPC的bitpacked记录,发现自己陷入了深深的麻烦之中。

我尝试读取的第一个结构具有以下格式:

{$BITPACKING ON}
type
  THeader = bitpacked record
    Magic: Byte;        // format id, 8 bits
    _Type: $000..$FFF;  // type specifier, 12 bits
    Version: Word;      // data revision, 16 bits
    Flags: $0..$F       // attributes, 4 bits
  end;


这是一个阅读代码:

procedure TForm1.FormCreate(Sender: TObject);
var
  F: File;
  Header: THeader;
begin
  Writeln(SizeOf(Header), #9, BitSizeOf(Header));   // reports correctly

  Writeln('SizeOf(Header._Type) = ', SizeOf(Header._Type));       // correctly reports 2 bytes
  Writeln('BitSizeOf(Header._Type) = ', BitSizeOf(Header._Type)); // correctly reports 12 bits

  AssignFile(F, 'D:\3fd8.dat');
  FileMode := fmOpenRead;
  Reset(F, SizeOf(Byte));
  BlockRead(F, Header, SizeOf(Header));

  { data is incorrect beyond this point already }

  //Header._Type := BEtoN(Header._Type);

  Writeln(IntToHex(Header.Magic, SizeOf(Header.Magic) * 2));
  Writeln(IntToHex(BEtoN(Header._Type), SizeOf(Header._Type) * 2));
  Writeln(BEtoN(Header.Version));
end;


但是代码正在打印完全错误的数据。

这是手动完成的数据和解释:

0000000000: F1 55 BE 3F 0A ...
Magic = F1
_Type = 55B
Version = E3F0
Flags = A


但是FPC以严重不同和错误的方式查看数据。似乎由于主机的字节序少,属于字段的半字节(和位)不连续(例如:半字节B通常应属于_Type字段,而半字节E-属于Version)。这是拉撒路的手表窗口:

delphi - Little-endian机器问题上的“bitpacked”记录-LMLPHP

请告知我该怎么做。这个非连续的位域是FPC的错误吗?有任何解决方法?

最佳答案

字节数

F1 55 BE 3F 0A


具有以下连续的半字节(高半字节之前是低半字节):

1 F 5 5 E B F 3 A 0


如果将它们分别分为2、3、4和1个半字节,则得到:

 1 F     --> $F1
 5 5 E   --> $E55   // highest nibble last, so E is highest.
 B F 3 A --> $A3FB  // same again: A is highest nibble
 0       --> $0


这对应于您在“监视”窗口中看到的结果,而不是您手动解码的结果。

现在,如果数据是big-endian格式,则必须使用移位和掩码手动解码:

X.Magic := bytes[0];
X._Type := (bytes[1] shl 4) or (bytes[2] shr 4);
X.Version := ((bytes[2] and $0F) shl 12) or
             (bytes[3] shl 4) or
             (bytes[4] shr 4);
X.Flags := bytes[4] and $0F;

关于delphi - Little-endian机器问题上的“bitpacked”记录,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31848246/

10-10 09:52