Looks like the solution is declaring the parameter type in the BUILD submethod. This one works fine:
use NativeCall; class test1 is repr('CStruct') is export { has uint64 $.a; has uint64 $.b; } class test2 is repr('CStruct') is export { has uint64 $.c; has test1 $.d; submethod BUILD(uint64 :$c, test1 :$d){ $!c = $c; $!d := $d; } } my test2 $t2 .= new(:3c, d => test1.new(:1a :2b)); dd $t2; On Sat, Oct 1, 2016 at 10:34 AM, Fernando Santagata < nando.santag...@gmail.com> wrote: > Hello, > > I'm trying to do something complex (at least for me :-) with NativeCall. > > Let's start with plain Perl6. This: > > class test1 { > has Int $.a; > has Int $.b; > } > > class test2 { > has Int $.c; > has test1 $.d; > } > > my test2 $t2 .= new(:3c, d => test1.new(:1a :2b)); > dd $t2; > > outputs: > > test2 $t2 = test2.new(c => 3, d => test1.new(a => 1, b => 2)) > > > But I need to do that with CStructs. This code: > > use NativeCall; > > class test1 is repr('CStruct') is export { > has uint64 $.a; > has uint64 $.b; > } > > class test2 is repr('CStruct') is export { > has uint64 $.c; > has test1 $.d; > } > > my test2 $t2 .= new(:3c, d => test1.new(:1a :2b)); > dd $t2; > > doesn't really work and outputs this: > > Cannot modify an immutable test1 > > > Adding a BUILD submethod isn't enough: > > submethod BUILD(:$!c, :$!d) { } > > What I get is: > > CStruct can't perform boxed get on flattened attributes yet > > > and this: > > submethod BUILD(:$c, :$d){ > $!c = $c; > $!d := $d; > } > > doesn't work either: > > Can only store CStruct attribute in CStruct slot in CStruct > > > But this one does: > > submethod BUILD(:$c, :$d){ > $!c = $c; > $!d := test1.new(a => $d.a, b => $d.b); > } > > Only, I don't want to initialize all the attributes one by one... > Is there a less cumbersome way to do that initialization? > > Thanks! > > -- > Fernando Santagata > -- Fernando Santagata