Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bit fields in NativeCall

I am trying to create Perl6 bindings for Cgraph, and one of the structs has bit fields set for some of its attributes with values under 8. How should I represent that in my module?

I have tried defining a custom type using the is nativesize(x) trait, but CStructs only support types that are a multiple of 8 bits wide.

C example code:

struct Agtag_s {
    unsigned objtype:2;
}

What I tried:

my native objtype is repr('P6int') is Int is nativesize(2) is export { }
class Agtag is repr('CStruct') is export {
    has objtype $.object-type;
}

Trying to use my module with that code fails with the following error message: CStruct only supports native types that are a multiple of 8 bits wide (was passed: 2)

like image 638
tmtvl Avatar asked Jun 26 '19 15:06

tmtvl


People also ask

What are bit fields in C++?

A bit field can be any integral type or enumeration type. End of C++ only. The maximum bit-field length is 64 bits. To increase portability, do not use bit fields greater than 32 bits in size.

How bit fields are stored in memory?

Again, storage of bit fields in memory is done with a byte-by-byte, rather than bit-by-bit, transfer.

Can we have an array of bit fields?

Arrays of bit fields, pointers to bit fields, and functions returning bit fields are not allowed. The optional declarator names the bit field. Bit fields can only be declared as part of a structure. The address-of operator (&) cannot be applied to bit-field components.

What are the important points to be considered when implementing bit fields in structures?

Bit fields can be used to reduce memory consumption when a program requires a number of integer variables which always will have low values. For example, in many systems storing an integer value requires two bytes (16-bits) of memory; sometimes the values to be stored actually need only one or two bits.

What are bitfields and how do I use them?

Bitfields are ranges of bits inside a variable that act as as a sub-variable. The basic operations here are set and get. For both of these, you need to careful not to disturb the other bits in the same variable (masking) and to shift left/right to align the value with the bitfield. The macros for these are BIT_SET () and BIT_GET () .

When do we use bit field in a byte?

When devices transmit status or information encoded into multiple bits for this type of situation bit-fiels is most effiecient. Encryption routines need to access the bits within a byte in that situation bit-field is quite useful.

What are the variable elements of a bit field?

The following table describes the variable elements of a bit field − An integer type that determines how a bit-field's value is interpreted. The type may be int, signed int, or unsigned int. The name of the bit-field. The number of bits in the bit-field. The width must be less than or equal to the bit width of the specified type.

What is bit-field width?

The number of bits in the bit-field. The width must be less than or equal to the bit width of the specified type. The variables defined with a predefined width are called bit fields.


1 Answers

Here is an example. I assume a function use_struct() is defined in a library libslib :

#include <stdio.h>

struct Agtag_s {
    unsigned objtype:2;
    unsigned footype:4;
    unsigned bartype:6;
};

void use_struct (struct Agtag_s *s) {
    printf("sizeof(struct Agtag_s): %ld\n", sizeof( struct Agtag_s ));
    printf("objtype = %d\n", s->objtype);
    printf("footype = %d\n", s->footype);
    printf("bartype = %d\n", s->bartype);
    s->objtype = 3;
    s->footype = 13;
    s->bartype = 55;
}

Then in Perl 6:

use v6;
use NativeCall;

class Agtag is repr('CStruct') is export {
    has int32 $.bitfield is rw;
}

sub use_struct(Agtag $s is rw) is native("./libslib.so") { * };

my $s = Agtag.new();
my $objtype = 1;
my $footype = 7;
my $bartype = 31;
$s.bitfield = $objtype +| ($footype +< 2 ) +| ($bartype +< 6);
say "Calling library function..";
say "--------------------------";
use_struct( $s );
say "After call..";
say "------------";
say "objtype = ", $s.bitfield +& 3;
say "footype = ", ($s.bitfield +> 2) +& 15;
say "bartype = ", ($s.bitfield +> 6) +& 63;

Output:

Calling library function..
--------------------------
sizeof(struct Agtag_s): 4
objtype = 1
footype = 7
bartype = 31
After call..
------------
objtype = 3
footype = 13
bartype = 55
like image 91
Håkon Hægland Avatar answered Dec 25 '22 17:12

Håkon Hægland