On 2019-12-29 14:56, ToddAndMargo via perl6-users wrote:
Hi All,

This is my keeper on Native Call.

-T

<perl6.Native.Call.Notes.txt>

Raku: Native Call notes:

Really poor reference: https://docs.raku.org/language/nativecall


1) Kernel32.dll call variables with a "p" in them are "C" pointers.

    LSTATUS RegOpenKeyExW(
        HKEY    hKey,
        LPCWSTR lpSubKey,
        DWORD   ulOptions,
        REGSAM  samDesired,
        PHKEY   phkResult
    );

     LPCWSTR and PHKEY in the above would be "C" pointers.

       A) Native Call converts Raku variables into C Pointer for you

       B) NativeCall converts the pointers to their contents of a
          returned “C” variable for you

2) to pass a "C" NULL to Native Call, send it a numerical zero.
    Note: in “C”, a NULL is a pointer whose value is zero

3) a “C” string is an array of characters terminated with chr(0)

4) Kernel32.dll calls with a “W” in them use UTF16 `uint16` values
    in their strings.  The rest you can use UTF8 `uint8`.  Most of
    the time they are interchangeable if you are using standard
    characters.

    Use the following to convert a Raku strings, `abcdefg` below,
    into a “C” string

       UTF8:  my $L =  CArray[uint8].new("abcdefg".encode.list);
       UTF16: my $M = CArray[uint16].new("abcdefg".encode.list);

    Native Call is tack the chr(0) at the end for you.

5) create two line to pass a call to Native Call (see 1) above for
    the call definition):

    constant WCHAR   := uint16;
    constant DWORD   := int32;

    sub RegQueryValueExW(
       DWORD,
       WCHARS,
       DWORD,
       DWORD,
       DWORD is rw,
       DWORD is rw
    )
       is native("Kernel32.dll")
       is symbol("RegQueryValueExW")
       returns DWORD
    { * };

    $RtnCode = RegQueryValueExW(
        $Handle, $lpValueName, 0, 0, $lpData, $lpcbData );

    $RtnCode is the Windows return error code.  Note: 0 is success

    $lpData is the actual data converted from the “C” pointer

    $lpcbData is the converted number of bytes in $lpData’s
    converted data

</perl6.Native.Call.Notes.txt>


Today's revised revision:

4) Kernel32.dll calls with a “W” in them use UTF16 `uint16` values
   in their strings.  The rest you can use UTF8 `uint8`.  Most of
   the time they are interchangeable if you are using standard
   characters.

   Use the following to convert a Raku strings, `abcdefg` below,
   into a “C” string

      UTF8:  my $L =  CArray[uint8].new("abcdefg".encode.list);
      UTF16: my $M = CArray[uint16].new("abcdefg".encode.list);

   Native Call is tack the chr(0) at the end for you, most of the time

   To tack a nul on the end (two nuls won't hurt anything)

      my $M = CArray[uint16].new("abcdefg".encode.list); $M[$M.elems] = 0
      Note: you can't use `push` as it is an "immutable 'List'"

   A sub to convert and tack on the nul:

      constant WCHAR              = uint16;
      sub to-c-str( Str $str ) returns CArray[WCHAR]  {
         my @str := CArray[WCHAR].new;
         for ( $str.comb ).kv -> $i, $char { @str[$i] = $char.ord; }
         @str[ $str.chars ] = 0;
         @str;
      }




--
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Computers are like air conditioners.
They malfunction when you open windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Reply via email to