Reputation: 83
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)
Upvotes: 8
Views: 104
Reputation: 40758
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
Upvotes: 6