如何模拟Delphi记录中的位域?
发布时间:2020-12-15 10:18:28 所属栏目:大数据 来源:网络整理
导读:我想在Delphi中声明一个包含与C中相同的布局的记录。 对于感兴趣的人:此记录是Windows操作系统的LDT_ENTRY记录中的联合的一部分。 (我需要在Delphi中使用这个记录,因为我正在Delphi中使用Xbox模拟器 – 请参阅sourceforge上的项目Dxbx)。 无论如何,有关记
我想在Delphi中声明一个包含与C中相同的布局的记录。
对于感兴趣的人:此记录是Windows操作系统的LDT_ENTRY记录中的联合的一部分。 (我需要在Delphi中使用这个记录,因为我正在Delphi中使用Xbox模拟器 – 请参阅sourceforge上的项目Dxbx)。 无论如何,有关记录定义为: struct { DWORD BaseMid : 8; DWORD Type : 5; DWORD Dpl : 2; DWORD Pres : 1; DWORD LimitHi : 4; DWORD Sys : 1; DWORD Reserved_0 : 1; DWORD Default_Big : 1; DWORD Granularity : 1; DWORD BaseHi : 8; } Bits; 据我所知,Delphi没有可能的位域。我试过这个: Bits = record BaseMid: Byte; // 8 bits _Type: 0..31; // 5 bits Dpl: 0..3; // 2 bits Pres: Boolean; // 1 bit LimitHi: 0..15; // 4 bits Sys: Boolean; // 1 bit Reserved_0: Boolean; // 1 bit Default_Big: Boolean; // 1 bit Granularity: Boolean; // 1 bit BaseHi: Byte; // 8 bits end; 但是唉:它的大小变成10字节,而不是预期的4。 TIA。 解决方法
感谢大家!
根据这些信息,我将其简化为: RBits = record public BaseMid: BYTE; private Flags: WORD; function GetBits(const aIndex: Integer): Integer; procedure SetBits(const aIndex: Integer; const aValue: Integer); public BaseHi: BYTE; property _Type: Integer index $0005 read GetBits write SetBits; // 5 bits at offset 0 property Dpl: Integer index $0502 read GetBits write SetBits; // 2 bits at offset 5 property Pres: Integer index $0701 read GetBits write SetBits; // 1 bit at offset 7 property LimitHi: Integer index $0804 read GetBits write SetBits; // 4 bits at offset 8 property Sys: Integer index $0C01 read GetBits write SetBits; // 1 bit at offset 12 property Reserved_0: Integer index $0D01 read GetBits write SetBits; // 1 bit at offset 13 property Default_Big: Integer index $0E01 read GetBits write SetBits; // 1 bit at offset 14 property Granularity: Integer index $0F01 read GetBits write SetBits; // 1 bit at offset 15 end; 索引编码如下:(BitOffset shl 8)NrBits。其中1≤NrBits<= 32且0 <= BitOffset = 31 现在,我可以得到并设置这些位如下: {$OPTIMIZATION ON} {$OVERFLOWCHECKS OFF} function RBits.GetBits(const aIndex: Integer): Integer; var Offset: Integer; NrBits: Integer; Mask: Integer; begin NrBits := aIndex and $FF; Offset := aIndex shr 8; Mask := ((1 shl NrBits) - 1); Result := (Flags shr Offset) and Mask; end; procedure RBits.SetBits(const aIndex: Integer; const aValue: Integer); var Offset: Integer; NrBits: Integer; Mask: Integer; begin NrBits := aIndex and $FF; Offset := aIndex shr 8; Mask := ((1 shl NrBits) - 1); Assert(aValue <= Mask); Flags := (Flags and (not (Mask shl Offset))) or (aValue shl Offset); end; 很漂亮,你不觉得吗? PS:Rudy Velthuis现在在他的优秀“Pitfalls of converting”-article中包含了这个修订版本。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |