Search code examples
rakunativecall

Raku: How do I assign values to CArray[WCHAR]?


$ raku -v This is Rakudo version 2019.07.1 built on MoarVM version 2019.07.1

The following was done on Raku REPL. What am I doing wrong here? How do I assign values to CArray[WCHAR]?

I want $lpData[0] to be 0xABCD and $lpData[1] to be 0xEF12.

> use NativeCall;
Nil

> constant WCHAR := uint16;
(uint16)

> my $ValueData = 0xABCDEF12;
2882400018

> my CArray[WCHAR]  $lpData;
(CArray[uint16])

> $lpData[ 0 ] =  ( $ValueData +& 0xFFFF0000 ) +> 0x10;
Type check failed in assignment to $lpData; expected NativeCall::Types::CArray[uint16] but got Array ($[])
  in block <unit> at <unknown file> line 1

> $lpData[ 1 ] =    $ValueData +& 0x0000FFFF;
Type check failed in assignment to $lpData; expected NativeCall::Types::CArray[uint16] but got Array ($[])
  in block <unit> at <unknown file> line 1

Many thanks, -T


Solution

  • The problem is stated clearly in the error message: in the way you declare it, it's expecting every item to be a CArray[WCHAR]. Declare it this way, as is indicated in the documentation:

    use NativeCall;
    constant WCHAR = uint16; # No need to bind here also
    my $native-array = CArray[WCHAR].new(); 
    $native-array[0] = 0xABCDEF12 +& 0x0000FFFF;
    say $native-array.list; # OUTPUT: «(-4334)␤»
    

    CArray is not exactly a Positional, but it does have AT-POS defined so you can use square brackets to assign values. The error arises when, you try to assign to an non-initialized Scalar (which contains any) as if it were an array. The minimal change from your program is just initializing to a CArray[WCHAR]:

    use NativeCall;
    constant WCHAR = uint16; # No need to bind here also
    my CArray[WCHAR] $native-array .= new; 
    $native-array[0] = 0xABCDEF12 +& 0x0000FFFF;
    say $native-array.list; # OUTPUT: «(-4334)␤»