C到Delphi转换union和struct与位域

时间:2012-04-17 18:59:14

标签: c delphi

有人可以解释如何转换

typedef struct _X86_SELECTOR
{
union
    {
    struct
        {
        WORD wValue;            // packed value
        WORD wReserved;
        };
    struct
        {
        unsigned RPL      :  2; // requested privilege level
        unsigned TI       :  1; // table indicator: 0=gdt, 1=ldt
        unsigned Index    : 13; // index into descriptor table
        unsigned Reserved : 16;
        };
    };
}
X86_SELECTOR, *PX86_SELECTOR, **PPX86_SELECTOR;

#define X86_SELECTOR_ sizeof (X86_SELECTOR)

// -----------------------------------------------------------------

typedef struct _X86_DESCRIPTOR
{
union
    {
    struct
        {
        DWORD dValueLow;        // packed value
        DWORD dValueHigh;
        };
    struct
        {
        unsigned Limit1   : 16; // bits 15..00
        unsigned Base1    : 16; // bits 15..00
        unsigned Base2    :  8; // bits 23..16
        unsigned Type     :  4; // segment type
        unsigned S        :  1; // type (0=system, 1=code/data)
        unsigned DPL      :  2; // descriptor privilege level
        unsigned P        :  1; // segment present
        unsigned Limit2   :  4; // bits 19..16
        unsigned AVL      :  1; // available to programmer 
        unsigned Reserved :  1;
        unsigned DB       :  1; // 0=16-bit, 1=32-bit
        unsigned G        :  1; // granularity (1=4KB)
        unsigned Base3    :  8; // bits 31..24
        };
    };
}
X86_DESCRIPTOR, *PX86_DESCRIPTOR, **PPX86_DESCRIPTOR;

1 个答案:

答案 0 :(得分:2)

没有直接翻译,因为Delphi不支持像C这样的位字段。最接近的交易将类似于以下内容:

type
  X86_SELECTOR = record
    case Integer of
      0: (
        wValue: WORD; // packed value
        wReserved: WORD);
      1: (
        BitValues: DWORD);
  end;
  PX86_SELECTOR = ^X86_SELECTOR;
  PPX86_SELECTOR = ^PX86_SELECTOR;

const
  X86_SELECTOR_ = SizeOf(X86_SELECTOR);

type
  X86_DESCRIPTOR = record
    case Integer of
      0: (
        dValueLow: DWORD; // packed value
        dValueHigh: DWORD);
      1: (
        BitFields1: DWORD;
        BitFields2: DWORD);
  end;
  PX86_DESCRIPTOR = ^X86_DESCRIPTOR;
  PPX86_DESCRIPTOR = ^PX86_DESCRIPTOR;

function X86_SELECTOR_Get_RPL(const Selector: X86_SELECTOR): Byte;
begin
  Result := Byte((Selector.BitValues and $C0000000) shr 30);
end;

procedure X86_SELECTOR_Set_RPL(var Selector: X86_SELECTOR; Value: Byte);
begin
  Selector.BitValues := (Selector.BitValues and $3FFFFFFF) or (DWORD(Value and $03) shl 30);
end;

function X86_SELECTOR_Get_TI(const Selector: X86_SELECTOR): Boolean;
begin
  Result := (Selector.BitValues and $20000000) <> 0;
end;

procedure X86_SELECTOR_Set_TI(var Selector: X86_SELECTOR; Value: Boolean);
begin
  Selector.BitValues := (Selector.BitValues and $DFFFFFFF) or (DWORD(Ord(Value)) shl 29);
end;

function X86_SELECTOR_Get_Index(const Selector: X86_SELECTOR): WORD;
begin
  Result := Word((Selector.BitValues and $1FFF0000) shr 16);
end;

procedure X86_SELECTOR_Set_Index(var Selector: X86_SELECTOR; Value: WORD);
begin
  Selector.BitValues := (Selector.BitValues and $E000FFFF) or (DWORD(Value and $1FFF) shl 16);
end;

function X86_SELECTOR_Get_Reserved(const Selector: X86_SELECTOR): Word;
begin
  Result := Word(Selector.BitValues and $FFFF);
end;

procedure X86_SELECTOR_Set_Reserved(var Selector: X86_SELECTOR; Value: Word);
begin
  Selector.BitValues := (Selector.BitValues and $FFFF0000) or DWORD(Value);
end;

function X86_DESCRIPTOR_Get_Limit1(const Descriptor: X86_DESCRIPTOR): Word;
begin
  Result := Word(Descriptor.BitFields1 and $FFFF0000) shr 16);
end;

procedure X86_DESCRIPTOR_Set_Limit1(var Descriptor: X86_DESCRIPTOR; Value: Word);
begin
  Descriptor.BitFields1 := (Descriptor.BitFields1 and $0000FFFF) or (DWORD(Value) shl 16);
end;

function X86_DESCRIPTOR_Get_Base1(const Descriptor: X86_DESCRIPTOR): Word;
begin
  Result := Word(Descriptor.BitFields1 and $0000FFFF);
end;

procedure X86_DESCRIPTOR_Set_Base1(var Descriptor: X86_DESCRIPTOR; Value: Word);
begin
  Descriptor.BitFields1 := (Descriptor.BitFields1 and $FFFF0000) or DWORD(Value);
end;

function X86_DESCRIPTOR_Get_Base2(const Descriptor: X86_DESCRIPTOR): Byte;
begin
  Result := Byte((Descriptor.BitFields2 and $FF000000) shr 24);
end;

procedure X86_DESCRIPTOR_Set_Base2(var Descriptor: X86_DESCRIPTOR; Value: Byte);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $00FFFFFF) or (DWORD(Value) shl 24);
end;

function X86_DESCRIPTOR_Get_Type(const Descriptor: X86_DESCRIPTOR): Byte;
begin
  Result := Byte((Descriptor.BitFields2 and $00F00000) shr 20);
end;

procedure X86_DESCRIPTOR_Set_Type(var Descriptor: X86_DESCRIPTOR; Value: Byte);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FF0FFFFF) or (DWORD(Value and $0F) shl 20);
end;

function X86_DESCRIPTOR_Get_S(const Descriptor: X86_DESCRIPTOR): Boolean;
begin
  Result := (Descriptor.BitFields2 and $00080000) <> 0;
end;

procedure X86_DESCRIPTOR_Set_S(var Descriptor: X86_DESCRIPTOR; Value: Boolean);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFF7FFFF) or (DWORD(Ord(Value)) shl 19);
end;

function X86_DESCRIPTOR_Get_DPL(const Descriptor: X86_DESCRIPTOR): Byte;
begin
  Result := Byte((Descriptor.BitFields2 and $00060000) shr 17);
end;

procedure X86_DESCRIPTOR_Set_DPL(var Descriptor: X86_DESCRIPTOR; Value: Byte);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFF9FFFF) or (DWORD(Value and $03) shl 17);
end;

function X86_DESCRIPTOR_Get_P(const Descriptor: X86_DESCRIPTOR): Boolean;
begin
  Result := (Descriptor.BitFields2 and $00010000) <> 0;
end;

procedure X86_DESCRIPTOR_Set_P(var Descriptor: X86_DESCRIPTOR; Value: Boolean);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFFEFFFF) or (DWORD(Ord(Value)) shl 16);
end;

function X86_DESCRIPTOR_Get_Limit2(const Descriptor: X86_DESCRIPTOR): Byte;
begin
  Result := Byte((Descriptor.BitFields2 and $0000F000) shr 12);
end;

procedure X86_DESCRIPTOR_Set_Limit2(var Descriptor: X86_DESCRIPTOR; Value: Byte);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFF9FFFF) or (DWORD(Value and $0F) shl 12);
end;

function X86_DESCRIPTOR_Get_AVL(const Descriptor: X86_DESCRIPTOR): Boolean;
begin
  Result := (Descriptor.BitFields2 and $00000800) <> 0;
end;

procedure X86_DESCRIPTOR_Set_AVL(var Descriptor: X86_DESCRIPTOR; Value: Boolean);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFFFF7FF) or (DWORD(Ord(Value)) shl 11);
end;

function X86_DESCRIPTOR_Get_Reserved(const Descriptor: X86_DESCRIPTOR): Boolean;
begin
  Result := (Descriptor.BitFields2 and $00000400) <> 0;
end;

procedure X86_DESCRIPTOR_Set_Reserved(var Descriptor: X86_DESCRIPTOR; Value: Boolean);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFFFFBFF) or (DWORD(Ord(Value)) shl 10);
end;

function X86_DESCRIPTOR_Get_DB(const Descriptor: X86_DESCRIPTOR): Boolean;
begin
  Result := (Descriptor.BitFields2 and $00000200) <> 0;
end;

procedure X86_DESCRIPTOR_Set_DB(var Descriptor: X86_DESCRIPTOR; Value: Boolean);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFFFFDFF) or (DWORD(Ord(Value)) shl 9);
end;

function X86_DESCRIPTOR_Get_G(const Descriptor: X86_DESCRIPTOR): Boolean;
begin
  Result := (Descriptor.BitFields2 and $00000100) <> 0;
end;

procedure X86_DESCRIPTOR_Set_G(var Descriptor: X86_DESCRIPTOR; Value: Boolean);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFFFFEFF) or (DWORD(Ord(Value)) shl 8);
end;

function X86_DESCRIPTOR_Get_Base3(const Descriptor: X86_DESCRIPTOR): Byte;
begin
  Result := Byte(Descriptor.BitFields2 and $000000FF);
end;

procedure X86_DESCRIPTOR_Set_Base3(var Descriptor: X86_DESCRIPTOR; Value: Byte);
begin
  Descriptor.BitFields2 := (Descriptor.BitFields2 and $FFFFFF00) or DWORD(Value);
end;

如果您使用支持记录属性的现代版Delphi,则可以执行以下操作:

type
  X86_SELECTOR = record
  private
    function Get_RPL: Byte;
    procedure Set_RPL(Value: Byte);
    function Get_TI: Boolean;
    procedure Set_TI(Value: Boolean);
    function Get_Index: WORD;
    procedure Set_Index(Value: WORD);
    function Get_Reserved: Word;
    procedure Set_Reserved(Value: Word);
  public
    property RPL: Byte read Get_RPL write Set_RPL;
    property TI: boolean read Get_TI write Set_TI;
    property Index: Word read Get_Index write Set_Index;
    property Reserved: Word read Get_Reserved write Set_Reserved;

    case Integer of
      0: (
        wValue: WORD; // packed value
        wReserved: WORD);
      1: (
        BitValues: DWORD);
  end;
  PX86_SELECTOR = ^X86_SELECTOR;
  PPX86_SELECTOR = ^PX86_SELECTOR;

const
  X86_SELECTOR_ = SizeOf(X86_SELECTOR);

type
  X86_DESCRIPTOR = record
  private
    function Get_Limit1: Word;
    procedure Set_Limit1(Value: Word);
    function Get_Base1: Word;
    procedure Set_Base1(Value: Word);
    function Get_Base2: Byte;
    procedure Set_Base2(Value: Byte);
    function Get_Type: Byte;
    procedure Set_Type(Value: Byte);
    function Get_S: Boolean;
    procedure Set_S(Value: Boolean);
    function Get_DPL: Byte;
    procedure Set_DPL(Value: Byte);
    function Get_P: Boolean;
    procedure Set_P(Value: Boolean);
    function Get_Limit2: Byte;
    procedure Set_Limit2(Value: Byte);
    function Get_AVL: Boolean;
    procedure Set_AVL(Value: Boolean);
    function Get_Reserved: Boolean;
    procedure Set_Reserved(Value: Boolean);
    function Get_DB: Boolean;
    procedure Set_DB(Value: Boolean);
    function Get_G: Boolean;
    procedure Set_G(Value: Boolean);
    function Get_Base3: Byte;
    procedure Set_Base3(Value: Byte);
  public
    property Limit1: Word read Get_Limit1 write Set_Limit1;
    property Base1: Word read Get_Base1 write Set_Base1;
    property Base2: Byte read Get_Base2 write Set_Base2;
    property Type: Byte read Get_Type write Set_Type;
    property S: Boolean read Get_S write Set_S;
    property DPL: Byte read Get_DPL write Set_DPL;
    property P: Boolean read Get_P write Set_P;
    property Limit2: Byte read Get_Limit2 write Set_Limit2;
    property AVL: Boolean read Get_AVL write Set_AVL;
    property Reserved: Boolean read Get_Reserved write Set_Reserved;
    property DB: Boolean read Get_DB write Set_DB;
    property G: Boolean read Get_G write Set_G;
    property Base3: Byte read Get_Base3 write Set_Base3;

    case Integer of
      0: (
        dValueLow: DWORD; // packed value
        dValueHigh: DWORD);
      1: (
        BitFields1: DWORD;
        BitFields2: DWORD);
  end;
  PX86_DESCRIPTOR = ^X86_DESCRIPTOR;
  PPX86_DESCRIPTOR = ^PX86_DESCRIPTOR;

function X86_SELECTOR.Get_RPL: Byte;
begin
  Result := Byte((Self.BitValues and $C0000000) shr 30);
end;

procedure X86_SELECTOR.Set_RPL(Value: Byte);
begin
  Self.BitValues := (Self.BitValues and $3FFFFFFF) or (DWORD(Value and $03) shl 30);
end;

function X86_SELECTOR.Get_TI: Boolean;
begin
  Result := (Self.BitValues and $20000000) <> 0;
end;

procedure X86_SELECTOR.Set_TI(Value: Boolean);
begin
  Self.BitValues := (Self.BitValues and $DFFFFFFF) or (DWORD(Ord(Value)) shl 29);
end;

function X86_SELECTOR.Get_Index: WORD;
begin
  Result := Word((Self.BitValues and $1FFF0000) shr 16);
end;

procedure X86_SELECTOR.Set_Index(Value: WORD);
begin
  Self.BitValues := (Self.BitValues and $E000FFFF) or (DWORD(Value and $1FFF) shl 16);
end;

function X86_SELECTOR.Get_Reserved: Word;
begin
  Result := Word(Self.BitValues and $FFFF);
end;

procedure X86_SELECTOR.Set_Reserved(Value: Word);
begin
  Self.BitValues := (Self.BitValues and $FFFF0000) or DWORD(Value);
end;

function X86_DESCRIPTOR.Get_Limit1: Word;
begin
  Result := Word(Self.BitFields1 and $FFFF0000) shr 16);
end;

procedure X86_DESCRIPTOR.Set_Limit1(Value: Word);
begin
  Self.BitFields1 := (Self.BitFields1 and $0000FFFF) or (DWORD(Value) shl 16);
end;

function X86_DESCRIPTOR.Get_Base1: Word;
begin
  Result := Word(Self.BitFields1 and $0000FFFF);
end;

procedure X86_DESCRIPTOR.Set_Base1(Value: Word);
begin
  Self.BitFields1 := (Self.BitFields1 and $FFFF0000) or DWORD(Value);
end;

function X86_DESCRIPTOR.Get_Base2: Byte;
begin
  Result := Byte((Self.BitFields2 and $FF000000) shr 24);
end;

procedure X86_DESCRIPTOR.Set_Base2(Value: Byte);
begin
  Self.BitFields2 := (Self.BitFields2 and $00FFFFFF) or (DWORD(Value) shl 24);
end;

function X86_DESCRIPTOR.Get_Type: Byte;
begin
  Result := Byte((Self.BitFields2 and $00F00000) shr 20);
end;

procedure X86_DESCRIPTOR.Set_Type(Value: Byte);
begin
  Self.BitFields2 := (Self.BitFields2 and $FF0FFFFF) or (DWORD(Value and $0F) shl 20);
end;

function X86_DESCRIPTOR.Get_S: Boolean;
begin
  Result := (Self.BitFields2 and $00080000) <> 0;
end;

procedure X86_DESCRIPTOR.Set_S(Value: Boolean);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFF7FFFF) or (DWORD(Ord(Value)) shl 19);
end;

function X86_DESCRIPTOR.Get_DPL: Byte;
begin
  Result := Byte((Self.BitFields2 and $00060000) shr 17);
end;

procedure X86_DESCRIPTOR.Set_DPL(Value: Byte);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFF9FFFF) or (DWORD(Value and $03) shl 17);
end;

function X86_DESCRIPTOR.Get_P: Boolean;
begin
  Result := (Self.BitFields2 and $00010000) <> 0;
end;

procedure X86_DESCRIPTOR.Set_P(Value: Boolean);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFFEFFFF) or (DWORD(Ord(Value)) shl 16);
end;

function X86_DESCRIPTOR.Get_Limit2: Byte;
begin
  Result := Byte((Self.BitFields2 and $0000F000) shr 12);
end;

procedure X86_DESCRIPTOR.Set_Limit2(Value: Byte);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFF9FFFF) or (DWORD(Value and $0F) shl 12);
end;

function X86_DESCRIPTOR.Get_AVL: Boolean;
begin
  Result := (Self.BitFields2 and $00000800) <> 0;
end;

procedure X86_DESCRIPTOR.Set_AVL(Value: Boolean);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFFFF7FF) or (DWORD(Ord(Value)) shl 11);
end;

function X86_DESCRIPTOR.Get_Reserved: Boolean;
begin
  Result := (Self.BitFields2 and $00000400) <> 0;
end;

procedure X86_DESCRIPTOR.Set_Reserved(Value: Boolean);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFFFFBFF) or (DWORD(Ord(Value)) shl 10);
end;

function X86_DESCRIPTOR.Get_DB: Boolean;
begin
  Result := (Self.BitFields2 and $00000200) <> 0;
end;

procedure X86_DESCRIPTOR.Set_DB(Value: Boolean);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFFFFDFF) or (DWORD(Ord(Value)) shl 9);
end;

function X86_DESCRIPTOR.Get_G: Boolean;
begin
  Result := (Self.BitFields2 and $00000100) <> 0;
end;

procedure X86_DESCRIPTOR.Set_G(Value: Boolean);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFFFFEFF) or (DWORD(Ord(Value)) shl 8);
end;

function X86_DESCRIPTOR.Get_Base3: Byte;
begin
  Result := Byte(Self.BitFields2 and $000000FF);
end;

procedure X86_DESCRIPTOR.Set_Base3(Value: Byte);
begin
  Self.BitFields2 := (Self.BitFields2 and $FFFFFF00) or DWORD(Value);
end;