小弟的在学习用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里要怎么实现啊?有类似的位域操作操作例子可供借鉴吗?
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里要怎么实现啊?有类似的位域操作操作例子可供借鉴吗?
解决方案 »
- 关于Delphi如何读取.txt文件内容。。。。。。。
- 如何在RAVE报表中调用数据库中字段值后,将数据前加两个00?
- 为什么ADOQuery.Delete; 删除不了数据??
- 在delphi里面有没有语句调用外部程序?
- HOT :做程序累了吗?来这里测测你的智商...[转至新浪]
- 别人要我给他看一小段程序
- Doa的TOracleDataSet组件修改问题
- 关于dbgrid的问题,这个问题应该对所有的人都有帮助吧..
- 上次看帖子,里面有个地方叫水园,在哪儿呀?
- 關于記錄的操作﹗﹗
- ado+SQLSERVER+socket三层数据库程序执行SQL的问题?
- 我创建一个VCL 为什么我不做生成象TDBGRID 的 Columns 设置Column(贴出源码解答)
就是这样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.
把一个32位整型赋值给联合: uAbc.WORD=12345678;
再通过联合解析出特定位的特殊含义(比如求速度): speed =(int)uAbc.Bits.Speed_BIT
即,这个整型的2进制的可以分成表达不同含义的几个位域,有什么办法可以不通过移位操作,象C一样
方便地直接取这些位域的值吗?谢谢!
f afdas分
sa分
saf是fs啊
sf sf杀fsaf fsd
afsaf杀
有哪位大侠可以现身说法一下?
只是数据的表示方式而已不过Delphi没有C这种位域操作
其实可以用Record的方法替代,自己封装即可,类似控件的属性读写方法,D2007的新特征,嘻嘻
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;