小弟的在学习用Delphi,遇到这样一个应用:
C里面定义一个联合
typedef union ABC
{
  UINT32 Word;
  struct
       {
       UINT32 ID_BIT        :3; 
        UINT32 Name_BIT      :8; 
        UINT32 Speed_BIT     :21;        
       }Bits;
}uAbc;
可以很方便滴取出ID,name,Speed,   只要int ID = (int)uAbc.Bits.ID_BIT就可以了。
Delphi里要怎么实现啊?有类似的位域操作操作例子可供借鉴吗?

解决方案 »

  1.   

    你这个只是定义了一个Type中在包含一个子Type而已。看看delphi的帮助,关于结构类型。
      

  2.   


    就是这样unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TA=record
        ID:Integer;
        Name:Integer;
      end;
      TB=record
        ID1:Integer;
        Name1:Integer;
      end;
      TRec=record
        A:integer;
        case Integer of
          0:(A1:TA);
          1:(B1:TB);
      end;
      TForm1 = class(TForm)
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
      m_Rec:TRec;
    begin
      m_Rec.A1.ID:=111;
      showmessage( IntToStr( m_Rec.A1.ID ) );
    end;end.
      

  3.   

    首先感谢hongqi162 大侠的回答!问得太急,忘记写明白了,我的想法是这么调用:
    把一个32位整型赋值给联合:                             uAbc.WORD=12345678;
    再通过联合解析出特定位的特殊含义(比如求速度):         speed =(int)uAbc.Bits.Speed_BIT 
    即,这个整型的2进制的可以分成表达不同含义的几个位域,有什么办法可以不通过移位操作,象C一样
    方便地直接取这些位域的值吗?谢谢!
      

  4.   

    发的是风沙
    f afdas分
    sa分
    saf是fs啊
    sf sf杀fsaf fsd
    afsaf杀
      

  5.   

    在我心中delphi是很强大的, 难道不能实现这个功能吗?有没有其他变通实现的办法呢?
    有哪位大侠可以现身说法一下?
      

  6.   

    俺的代码从来不用联合,不照样能用?
    只是数据的表示方式而已不过Delphi没有C这种位域操作
    其实可以用Record的方法替代,自己封装即可,类似控件的属性读写方法,D2007的新特征,嘻嘻
      

  7.   

    操作方法应该和这个类似BitsetsSometimes you'll encounter a declaration like the following:typedef struct _RTCP_RECEIVER_REPORT {
        DWORD FractionLost:8;
        DWORD TotalLostPackets:24;
        DWORD HighestSequenceNum;
        DWORD InterarrivalJitter;
        DWORD LastSRTimestamp;
        DWORD DelaySinceLastSR;
    } RTCP_RECEIVER_REPORT, *PRTCP_RECEIVER_REPORT;The problem with the above declaration is, that it contains a C bitset. FractionLost and TotalLostPackets are not DWORDs at all. The :8 following the identifier FractionLost means that FractionLost only occupies 8 bits in a DWORD, and :24 means that TotalLostPackets contains the remainging 24 bits. So together they occupy one DWORD, not each one of its own. Such items are very hard to translate. Note: translation is platform dependent as well, but since this article is primarily for Win32, or at least Intel, you can disregard that.I would translate this as:type
      PRTCP_RECEIVER_REPORT = ^RTCP_RECEIVER_REPORT;
      _RTCP_RECEIVER_REPORT = record
        FractionLost_TotalLostPackets: DWORD; 
          // DWORD FractionLost:8
          // DWORD TotalLostPackets:24
        HighestSequenceNum: DWORD;
        InterarrivalJitter: DWORD;
        LastSRTimestamp: DWORD;
        DelaySinceLastSR: DWORD;
      end;
      RTCP_RECEIVER_REPORT = _RTCP_RECEIVER_REPORT;FractionLost could have been translated as a Byte, but that would not solve the problem with TotalLostPackets, since there are no 3 byte types that could be used for it. This way, if the user attempts to access either member, he will get a message that the identifeir is not defined, and have to look for himself. Often, you will have many items of 1 or 2 bits in size, so you have the chance to be creative with your identifiers.There is no way you can declare the items in Delphi thus, that they are readily accessible. You could provide constants for the shift and the mask to access the single parts of the DWORD, or even an enumerated type and a function to access the parts, but that is up to you. The user will most of the time have to do something extra to access the bit fields.An example for constants to acess the bit fields:// Assumes first "shr", then "and"
    const
      // shifts for FractionLost_TotalLostPackets field
      shrFractionLost = 0;
      shrTotalLostPackets = 8;
       
      // masks for FractionLost_TotalLostPackets field
      andFractionLost = $000000FF;
      andTotalLostPackets = $00FFFFFF;Now the TotalLostPackets bit field can be accessed like:LostPackets := Report.FractionLost_TotalLostPackets 
                     shr shrTotalLostPackets 
                     and andTotalLostPackets;Of course, you can also write access functions for each of the bitfields, something like:function FractionLost(const Report: RTCP_RECEIVER_REPORT): Byte; overload;
    begin
      Result := Report.FractionLost_TotalLostPackets and $000000FF;
    end;procedure FractionLost(var Report: RTCP_RECEIVER_REPORT; Value: Byte); overload;
    begin
      Report.FractionLost_TotalLostPackets := 
        (Report.FractionLost_TotalLostPackets and $FFFFFF00) or Value;
    end;// etc...It is used like:var
      Fraction: Integer;
      R: RTCP_RECEIVER_REPORT;
    begin
      Fraction := FractionLost(R);
      FractionLost(R, Fraction * 2);
    end;