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