Jump to content
shineworld

union with bitfields

Recommended Posts

Hi all.
I've to convert a Builder C++ code to Delphi which uses bitfiels in union and I don't know where to start and if it is possible:

// define QCL data types
typedef short   QCL_WORD;

typedef union {
    QCL_WORD data;
    struct {
        QCL_WORD alarm_state            :1;                 // bus flags: alarm state
        QCL_WORD alignment_state        :1;                 // bus flags: alignment state
        QCL_WORD inversion_wait         :1;                 // bus flags: external synchronism - inversion wait
        QCL_WORD out_of_min_bound       :1;                 // bus flags: column position is out of minimum boundaries
        QCL_WORD out_of_max_bound       :1;                 // bus flags: column position is out of maximum boundaries
        QCL_WORD below_safety_height    :1;                 // bus flags: column position is below safety height
        QCL_WORD in_working_pos         :1;                 // bus flags: column position is in working position
        QCL_WORD locking_latch_state    :1;                 // bus flags: column position in locking latch state
        QCL_WORD battery_warning        :1;                 // bus flags: column in battery warning
        QCL_WORD battery_alarm          :1;                 // bus flags: column in battery alarm
        QCL_WORD evr_state              :1;                 // bus flags: column EVR state
        QCL_WORD load_weight_zone       :2;                 // bus flags: column in load weight zone
        QCL_WORD column_is_consistent   :1;                 // bus flags: column in load weight zone
        QCL_WORD lift_set_acquire_req   :1;                 // bus flags: columns lift set acquire request
        QCL_WORD movement_mode_absolute :1;                 // bus flags: column has movement mode absolute
    } fields;
} t_bus_flags_w4;

Thanks in advance for any suggestion.
Best regards

Share this post


Link to post
Posted (edited)

Is this something that could match your needs? (untested)
 

type
  QCL_WORD = SmallInt;

  t_bus_flags_w4 = record
  private
    data: QCL_WORD;
    function GetBit(Index: Integer): Boolean;
    procedure SetBit(Index: Integer; Value: Boolean);
  public
    property AlarmState: Boolean index 0 read GetBit write SetBit;
    property AlignmentState: Boolean index 1 read GetBit write SetBit;
    property InversionWait: Boolean index 2 read GetBit write SetBit;
    property OutOfMinBound: Boolean index 3 read GetBit write SetBit;
    property OutOfMaxBound: Boolean index 4 read GetBit write SetBit;
    property BelowSafetyHeight: Boolean index 5 read GetBit write SetBit;
    property InWorkingPos: Boolean index 6 read GetBit write SetBit;
    property LockingLatchState: Boolean index 7 read GetBit write SetBit;
    property BatteryWarning: Boolean index 8 read GetBit write SetBit;
    property BatteryAlarm: Boolean index 9 read GetBit write SetBit;
    property EVRState: Boolean index 10 read GetBit write SetBit;
    property LoadWeightZone: Byte index 11 read GetBit write SetBit; // 2 Bits
    property ColumnIsConsistent: Boolean index 13 read GetBit write SetBit;
    property LiftSetAcquireReq: Boolean index 14 read GetBit write SetBit;
    property MovementModeAbsolute: Boolean index 15 read GetBit write SetBit;
  end;

implementation

function t_bus_flags_w4.GetBit(Index: Integer): Boolean;
begin
  Result := (data and (1 shl Index)) <> 0;
end;

procedure t_bus_flags_w4.SetBit(Index: Integer; Value: Boolean);
begin
  if Value then
    data := data or (1 shl Index)
  else
    data := data and not (1 shl Index);
end;

// For 2-Bit-Property LoadWeightZone we need some special Getter and Setter

function t_bus_flags_w4.GetLoadWeightZone: Byte;
begin
  Result := (data shr 11) and 3; // Extract 2 Bits at Position 11
end;

procedure t_bus_flags_w4.SetLoadWeightZone(Value: Byte);
begin
  data := (data and not ($3 shl 11)) or ((Value and $3) shl 11); // Set 2 Bits at Position 11
end;

 

Edited by Rollo62
  • Like 1

Share this post


Link to post
1 hour ago, shineworld said:

I've to convert a Builder C++ code to Delphi which uses bitfiels in union and I don't know where to start and if it is possible

Delphi doesn't support bitfields, so you have to do the bit-twiddling manually, as Rollo62 demonstrated.

https://stackoverflow.com/questions/282019/how-to-simulate-bit-fields-in-delphi-records

 

If it wasn't for the load_weight_zone field being 2 bits, you could have just used a plain Delphi 'Set of enum' instead.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×