delphi 里怎么实现联合?
小弟的在学习用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里要怎么实现啊?有类似的位域操作操作例子可供借鉴吗?
[解决办法]
你这个只是定义了一个Type中在包含一个子Type而已。看看delphi的帮助,关于结构类型。
[解决办法]
- Delphi(Pascal) code
就是这样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.
[解决办法]
联合是支持的, 但位域是不支持的.
[解决办法]
俺的代码从来不用联合,不照样能用?
只是数据的表示方式而已
不过Delphi没有C这种位域操作
其实可以用Record的方法替代,自己封装即可,类似控件的属性读写方法,D2007的新特征,嘻嘻
[解决办法]
- Delphi(Pascal) code
操作方法应该和这个类似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;