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)
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.
Again, storage of bit fields in memory is done with a byte-by-byte, rather than bit-by-bit, transfer.
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.
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.
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 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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With