Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


ID: 26612, Bit fields and Delphi

by Al Gun Email: Anonymous


How to deal C structure bit fields in Pascal?
Download Details
FTP  download also available 0 bytes
CDN Login Required to Download. (You will be redirected to the login page if you click on the Download Link)
To download this, you must have registered:
A free membership

For Delphi, Version 1.0  to 7.0 0 downloads
Copyright: No significant restrictions


Size: 0 bytes
Updated on Sun, 25 Jan 2009 07:26:02 GMT
Originally uploaded on Sun, 25 Jan 2009 07:26:02 GMT
Description
During translation of C files to Delphi, you might encounter
bit-field records, like following:

// This code is taken from PDH.H file

typedef struct _BrowseDlgConfig_A {
// Configuration flags
DWORD bIncludeInstanceIndex:1,
bSingleCounterPerAdd:1,
bSingleCounterPerDialog:1,
bLocalCountersOnly:1,
bWildCardInstances:1,
bHideDetailBox:1,
bInitializePath:1,
bDisableMachineSelection:1,
bIncludeCostlyObjects:1,
bShowObjectBrowser:1,
bReserved:22;

HWND hWndOwner;
LPSTR szDataSource;
__field_ecount(cchReturnPathLength) LPSTR szReturnPathBuffer;
DWORD cchReturnPathLength;
CounterPathCallBack pCallBack;
DWORD_PTR dwCallBackArg;
PDH_STATUS CallBackStatus;
DWORD dwDefaultDetailLevel;
LPSTR szDialogBoxCaption;
} PDH_BROWSE_DLG_CONFIG_A, * PPDH_BROWSE_DLG_CONFIG_A;

Now, Configuration flags field declared as DWORD and listed bunch of field with
values assigned to them, actually they are not values but fields width in a single
DWORD value which is not given above sample.

There are few choices:
If you are using Delphi versions 2006 and higher you are in luck, because
records with methods and properties available for you, but if you are using
lower version such as V7.0 or you dont want to get too much trouble with
getters and setters then following simple translation might help!

First of all translate sample code as usual:

_BrowseDlgConfig_A = record
// Configuration flags
BitField: DWORD;

hWndOwner : HWND;
szDataSource : PAnsiChar;
szReturnPathBuffer : PAnsiChar;
cchReturnPathLength : DWORD;
pCallBack : CounterPathCallBack;
dwCallBackArg : DWORD;
CallBackStatus : PDH_STATUS;
dwDefaultDetailLevel : DWORD;
szDialogBoxCaption : PAnsiChar;
end;
PDH_BROWSE_DLG_CONFIG_A = _BrowseDlgConfig_A;
PPDH_BROWSE_DLG_CONFIG_A = ^_BrowseDlgConfig_A;
PDH_BROWSE_DLG_CONFIG = _BrowseDlgConfig_A;
PPDH_BROWSE_DLG_CONFIG = ^_BrowseDlgConfig_A;

As you can see from sample translation, 11 fields disappeared, instead new
field introduced "BitField" or you can name it anything you like. The trouble
here is that if you want to access those fields in the application, you will get
"Unknown identifier" message.

Here is the solution!

Next, declare those fields as constants and index them in DWORD, how?

// Binary form of a DWORD value,

// 1098765431098765432109876543210 // 32 bit value
// 0000000000000000000000000000000 // decimal 0, hexadecimal $0

// Bit fields Mask (index) constants
const

// index calculation: first two bits <width>, last two bits <offset> or <location>
// of this bit in the DWORD value.

bIncludeInstanceIndex = $0001; // 1 bit at offset 0
bSingleCounterPerAdd = $0101; // 1 bit at offset 1
bSingleCounterPerDialog = $0201; // 1 bit at offset 2
bLocalCountersOnly = $0301; // 1 bit at offset 3
bWildCardInstances = $0401; // 1 bit at offset 4
bHideDetailBox = $0501; // 1 bit at offset 5
bInitializePath = $0601; // 1 bit at offset 6
bDisableMachineSelection = $0701; // 1 bit at offset 7
bIncludeCostlyObjects = $0801; // 1 bit at offset 8
bShowObjectBrowser = $0901; // 1 bit at offset 9
bReserved = $1601; // 1 bit at offset 22

// As intructed from variety companies, do not use anything says "reserved"
// in a record declaration. Just clear them and leave them alone!!!

// Helper procedure to set bitfields
procedure SetBits(var Bits: DWORD; const index, value: integer);
var
Offset: Byte;
Mask: integer;
begin
Mask:= ((1 shl Byte(index)) - 1);
Assert(value <= Mask);

Offset:= index shr 8;
Bits:= (Bits and (not(Mask shl Offset))) or DWORD(value shl Offset);
end;

If I want to set or reset, say for example, bit 7, I can use following
code to do that for me,

procedure SetBits(BitField, bDisableMachineSelection, integer(TRUE)); // to set
// 1098765431098765432109876543210 // 32 bit value
// 0000000000000000000000010000000 // decimal 128, hexadecimal $80

procedure SetBits(BitField, bDisableMachineSelection, integer(FALSE)); // to reset
// 1098765431098765432109876543210 // 32 bit value
// 0000000000000000000000000000000 // decimal 0, hexadecimal $0

if I want to set multiple bits, in this case I can use following code:

procedure SetBits(BitField, bIncludeInstanceIndex, integer(TRUE)); // to set
procedure SetBits(BitField, bSingleCounterPerAdd, integer(TRUE)); // to set
procedure SetBits(BitField, bSingleCounterPerDialog, integer(TRUE)); // to set
procedure SetBits(BitField, bHideDetailBox, integer(TRUE)); // to set
procedure SetBits(BitField, bIncludeCostlyObjects, integer(TRUE)); // to set
procedure SetBits(BitField, bShowObjectBrowser, integer(TRUE)); // to set

// 1098765431098765432109876543210 // 32 bit value
// 0000000000000000000001100100111 // decimal 807, hexadecimal $327
| | | | | |
| | | | | |_____ bIncludeInstanceIndex - set
| | | | |______ bSingleCounterPerAdd - set
| | | |_______ bSingleCounterPerDialog - set
| | |__________ bHideDetailBox - set
| |_____________ bIncludeCostlyObjects - set
|______________ bShowObjectBrowser - set



That's all!

Happy coding!

Ural Gunaydin
Australia

   Latest Comments  View All Add New

Move mouse over comment to see the full text

Could not retrieve comments. Please try again later.

Server Response from: ETNACDC04