develooper Front page | perl.perl6.users | Postings from December 2019

Re: My Native Call notes

Thread Previous | Thread Next
From:
ToddAndMargo via perl6-users
Date:
December 30, 2019 01:05
Subject:
Re: My Native Call notes
Message ID:
7c9ef7c5-efa4-de12-e019-1f6d6072c8a4@zoho.com
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About