Re: Nativecall - Help with converting wchar_t CArray to something printable

2021-01-02 Thread Paul Procacci
 I don't have a C string that's terminated by null.
I have a CArray[int16] of length 260 that's passed to and filled in by the
windows api.

https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot
https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-process32first
https://docs.microsoft.com/en-us/windows/win32/api/tlhelp32/nf-tlhelp32-process32next

Take the following for example which I quickly whipped up that is supposed
to iterate over the processes running on the given windows machine:

-

use NativeCall;

constant \MAX_PATH = 260;
constant \TH32CS_SNAPPROCESS = 0x0002;

class PROCESSENTRY32 is repr('CStruct') {
has int32 $.dwSize;
has int32 $.cntUsage;
has int32 $.th32ProcessID;
has int32 $.th32DefaultHeapID;
has int32 $.th32ModuleID;
has int32 $.cntThreads;
has int32 $.th32ParentProcessID;
has int32 $.pcPriClassBase;
has int32 $.dwFlags is rw;
HAS uint16 @.szExeFile[MAX_PATH] is CArray;
};

sub CreateToolhelp32Snapshot(int32, int32 --> Pointer) is
native('Kernel32') { * };
sub Process32First(Pointer, Pointer --> Bool) is native('Kernel32') { * };
sub Process32Next(Pointer, Pointer --> Bool) is native('Kernel32') { * };

my $ptr = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
die 'Failed to retreive process list.' if $ptr == Bool::False;
my PROCESSENTRY32 $entry .= new(:dwSize(nativesizeof(PROCESSENTRY32)));
die 'Unable to iterate over process list' if Process32First($ptr,
nativecast(Pointer, $entry)) == Bool::False;

repeat {
say $entry.szExeFile[0].ord;
say $entry.szExeFile[1].ord;
} while Process32Next($ptr, nativecast(Pointer, $entry));

--

The output of the above is:
48
48

This is clearly wrong.  This is either a) my misunderstanding of these
api calls b) raku bug or c) a usage error on my part.

~Paul


On Sun, Jan 3, 2021 at 2:12 AM ToddAndMargo via perl6-users <
perl6-users@perl.org> wrote:

> On 1/2/21 8:13 PM, Paul Procacci wrote:
> > What I'm trying to attempt to do now is display the contents of that
> > CArray (raku member a).  In my mind, this is an "array of utf16LE byte
> > sequences terminated by 0".
>
> Hi Paul,
>
> If I understand your problem, you are having trouble
> extracting something usable from Windows return UTF16
> string.
>
> I have a series of modules I wrote to read and write
> to the Windows registry.  The strings I got back were
> all "UTF16 little ending C Strings".
>
> This means that every character is a TWO byte word
> (16 bits) with the first byte containing the low
> value byte.  And they terminate with both bytes
> being a numerical zero.  It is a little weird to get
> use to.
>
> There was some interesting conversation in these
> parts a bit ago as to if a C string could ever
> not be terminated with a nul.  They are always
> terminated with a nul.
>
> The following is from one of the modules I wrote to
> support this.  I used brute force, rather than
> rely on UTF conversion utilities as I found them
> unreliable.
>
> If you un-comment
> # print $CStr[ $i ] ~ "," ~ $CStr[ $i + 1 ] ~ ",  ";
> you can watch the sub do its thing.
>
> I have a sub to go the other way too, if you want it.
>
> HTH,
> -T
>
>
>
> use NativeCall;
>
> sub c-to-raku-str( BYTES $CStr ) returns Str  is export( :c-to-raku-str ) {
> # Note: C Strings are always terminated with a nul.  This sub will
> malfunction without it.
> # Note: presumes a UTF16 little endian C String and converts to UTF8
>
> my Str$SubName   = &?ROUTINE.name;
> my Str$RakuStr   = "";
> my Str$Msg   = "";
> my uint32 $CStrElems = $CStr.elems;
> # say $CStrElems;
>
> loop (my $i = 0; $i < $CStrElems - 2 ; $i += 2) {
>if  $CStr[ $i ] == 0  &&  $CStr[ $i + 1 ] == 0  { last; }
>
>if $i == $CStrElems - 4  {
>   $Msg = "$SubName ERROR:" ~ " C Strings are required to be
> terminated with a nul\n\n" ~
>  " Returning an empty string\n" ~
>  " Cowardly existing\n";
>   exit;
>}
>
># print $CStr[ $i ] ~ "," ~ $CStr[ $i + 1 ] ~ ",  ";
>$RakuStr ~= chr( $CStr[ $i ] );
> }
> # say "";
>
> # say "$RakuStr";
> return $RakuStr;
> }
>
>
>

-- 
__

:(){ :|:& };:


Re: Nativecall - Help with converting wchar_t CArray to something printable

2021-01-02 Thread ToddAndMargo via perl6-users

On 1/2/21 8:13 PM, Paul Procacci wrote:

What I'm trying to attempt to do now is display the contents of that
CArray (raku member a).  In my mind, this is an "array of utf16LE byte 
sequences terminated by 0".


Hi Paul,

If I understand your problem, you are having trouble
extracting something usable from Windows return UTF16
string.

I have a series of modules I wrote to read and write
to the Windows registry.  The strings I got back were
all "UTF16 little ending C Strings".

This means that every character is a TWO byte word
(16 bits) with the first byte containing the low
value byte.  And they terminate with both bytes
being a numerical zero.  It is a little weird to get
use to.

There was some interesting conversation in these
parts a bit ago as to if a C string could ever
not be terminated with a nul.  They are always
terminated with a nul.

The following is from one of the modules I wrote to
support this.  I used brute force, rather than
rely on UTF conversion utilities as I found them
unreliable.

If you un-comment
   # print $CStr[ $i ] ~ "," ~ $CStr[ $i + 1 ] ~ ",  ";
you can watch the sub do its thing.

I have a sub to go the other way too, if you want it.

HTH,
-T



use NativeCall;

sub c-to-raku-str( BYTES $CStr ) returns Str  is export( :c-to-raku-str ) {
   # Note: C Strings are always terminated with a nul.  This sub will 
malfunction without it.

   # Note: presumes a UTF16 little endian C String and converts to UTF8

   my Str$SubName   = &?ROUTINE.name;
   my Str$RakuStr   = "";
   my Str$Msg   = "";
   my uint32 $CStrElems = $CStr.elems;
   # say $CStrElems;

   loop (my $i = 0; $i < $CStrElems - 2 ; $i += 2) {
  if  $CStr[ $i ] == 0  &&  $CStr[ $i + 1 ] == 0  { last; }

  if $i == $CStrElems - 4  {
 $Msg = "$SubName ERROR:" ~ " C Strings are required to be 
terminated with a nul\n\n" ~

" Returning an empty string\n" ~
" Cowardly existing\n";
 exit;
  }

  # print $CStr[ $i ] ~ "," ~ $CStr[ $i + 1 ] ~ ",  ";
  $RakuStr ~= chr( $CStr[ $i ] );
   }
   # say "";

   # say "$RakuStr";
   return $RakuStr;
}




Re: Nativecall - Help with converting wchar_t CArray to something printable

2021-01-02 Thread Paul Procacci
A follow-up to my initial message.

I think the following is relevant:

https://github.com/rakudo/rakudo/issues/3633

I think my inlined array is actually being filled with zero's.

say $a.a[0];
say $a.a[1];

Yields:

0
0

I'm using the comma ide:

>raku -v
Welcome to Rakudo(tm) v2020.12.
Implementing the Raku(tm) programming language v6.d.
Built on MoarVM version 2020.12.

~Paul

On Sat, Jan 2, 2021 at 11:13 PM Paul Procacci  wrote:

> Hey gents (again),
>
> I'm having on awful time with decoding UTF16LE character sequences that
> are placed into a Nativecall CArray that I've defined as an interface
> between Raku and a windows library call.
>
> The structure used by the windows function includes a static wchar_t field
> that's PATH_MAX in
> length (260 wchar_t's).  It would look like the following in C:
>
> struct Something {
>   int32_t dwSize;
>   wchar_t a[260];
> };
>
> I've written the following as the Raku counterpart to the above:
>
> class Something is repr('CStruct') {
>has int32 $.dwsize;
>HAS int16 @.a[260] is CArray;
> };
>
> Given the following definition for the windows library call:
>
> bool Test(Something *x);
>
> .. I've defined the following on the raku side of things:
>
> sub Test(Pointer --> Bool) is native('Kernel32') { * };
>
> --
>
> The function is supposed to write characters into the space allotted,
> namely a.
> The only required set member prior to calling the subroutine is that the
> size of the structure.
> It gets set in dwSize like so:
>
> my Something $a .= new(:dwSize(nativesizeof(Something)));
>
> Then the actual function call from the raku side of things:
>
> Test(nativecast(Pointer, $a));
>
> --
>
> All the above is working.  What I'm trying to attempt to do now is display
> the contents of that
> CArray (raku member a).  In my mind, this is an "array of utf16LE byte
> sequences terminated by 0".
>
> What's the cleanest way of doing this in raku?  I've tried variations of
> "join" and "encode", simple printf's, say's, etc., and even tried
> manipulating this data with Buf's, but I can't seem to get it quite right.
>
> Any help is appreciated.
> ~Paul
> --
> __
>
> :(){ :|:& };:
>


-- 
__

:(){ :|:& };:


Nativecall - Help with converting wchar_t CArray to something printable

2021-01-02 Thread Paul Procacci
Hey gents (again),

I'm having on awful time with decoding UTF16LE character sequences that are
placed into a Nativecall CArray that I've defined as an interface between
Raku and a windows library call.

The structure used by the windows function includes a static wchar_t field
that's PATH_MAX in
length (260 wchar_t's).  It would look like the following in C:

struct Something {
  int32_t dwSize;
  wchar_t a[260];
};

I've written the following as the Raku counterpart to the above:

class Something is repr('CStruct') {
   has int32 $.dwsize;
   HAS int16 @.a[260] is CArray;
};

Given the following definition for the windows library call:

bool Test(Something *x);

.. I've defined the following on the raku side of things:

sub Test(Pointer --> Bool) is native('Kernel32') { * };

--

The function is supposed to write characters into the space allotted,
namely a.
The only required set member prior to calling the subroutine is that the
size of the structure.
It gets set in dwSize like so:

my Something $a .= new(:dwSize(nativesizeof(Something)));

Then the actual function call from the raku side of things:

Test(nativecast(Pointer, $a));

--

All the above is working.  What I'm trying to attempt to do now is display
the contents of that
CArray (raku member a).  In my mind, this is an "array of utf16LE byte
sequences terminated by 0".

What's the cleanest way of doing this in raku?  I've tried variations of
"join" and "encode", simple printf's, say's, etc., and even tried
manipulating this data with Buf's, but I can't seem to get it quite right.

Any help is appreciated.
~Paul
-- 
__

:(){ :|:& };:


Re: NativeCall -- size of data structure

2021-01-02 Thread Paul Procacci
nativesizeof is what I was looking for.

Thanks,

~Paul


On Sat, Jan 2, 2021 at 8:39 PM ToddAndMargo via perl6-users <
perl6-users@perl.org> wrote:

> On 1/2/21 4:58 PM, Paul Procacci wrote:
> > Hey Gents,
> >
> > Hopefully a simple question that I could not find the answer to.
> >
> > Given the following:
> >
> > class PROCESSENTRY32 is repr('CStruct') {
> >  has int32 $.dwSize;
> >  has int32 $.cntUsage;
> >  has int32 $.th32ProcessID;
> >  has Pointer $.th32DefaultHeapID;
> >  has int32 $.th32ModuleID;
> >  has int32 $.cntThreads;
> >  has int32 $.th32ParentProcessID;
> >  has long $.pcPriClassBase;
> >  has int32 $.dwFlags;
> >  HAS Str @.szExeFile[260] is CArray;# MAX_PATH on windows is 260
>
> Did you mean to capitalize the HAS?
>
> > };
> >
> >
> > ... is there is a raku method that gives me the size of this data
> structure?
> >
> > In C for example one would use sizeof() to provide the size.  In raku I
> > could not find the documentation that would provide this information.
> >
> > Thanks,
> > Paul Procacci
>
> Hi Paul,
>
> Not that I know of.  Raku has a lot of things in
> the background of its structures that C does not.
>
> C does not have OOP (object orientated programming)
> but does have "struct", which is close enough.
>
> What you are trying to do is match the C structure
> of the system call with Raku's OOP "class".  In Raku,
> "class" is the definition of a structure and not the
> structure itself -- very much like C's "struct".
>
> You don't get an actual structure until you
> declare one from the class.  For example:
>
>  my $x = PROCESSENTRY32.new;
>
> And it is going to be a lot bigger behind the scenes
> that just adding up the bits.  You really do not need
> to know the behind the scene details anyway.  Raku
> strives to remove the need for the programmer to
> have to know these kind of details, unlike C.
>
> What system call are you trying to run?
>
> I have an example of how to read Windows Time
> that also uses OOP (class, object, and method).
> Let me know if you want it
>
> -T
>
>
>
>

-- 
__

:(){ :|:& };:


Re: NativeCall -- size of data structure

2021-01-02 Thread ToddAndMargo via perl6-users

On 1/2/21 4:58 PM, Paul Procacci wrote:

Hey Gents,

Hopefully a simple question that I could not find the answer to.

Given the following:

class PROCESSENTRY32 is repr('CStruct') {
 has int32 $.dwSize;
 has int32 $.cntUsage;
 has int32 $.th32ProcessID;
 has Pointer $.th32DefaultHeapID;
 has int32 $.th32ModuleID;
 has int32 $.cntThreads;
 has int32 $.th32ParentProcessID;
 has long $.pcPriClassBase;
 has int32 $.dwFlags;
 HAS Str @.szExeFile[260] is CArray;# MAX_PATH on windows is 260


Did you mean to capitalize the HAS?


};


... is there is a raku method that gives me the size of this data structure?

In C for example one would use sizeof() to provide the size.  In raku I 
could not find the documentation that would provide this information.


Thanks,
Paul Procacci


Hi Paul,

Not that I know of.  Raku has a lot of things in
the background of its structures that C does not.

C does not have OOP (object orientated programming)
but does have "struct", which is close enough.

What you are trying to do is match the C structure
of the system call with Raku's OOP "class".  In Raku,
"class" is the definition of a structure and not the
structure itself -- very much like C's "struct".

You don't get an actual structure until you
declare one from the class.  For example:

my $x = PROCESSENTRY32.new;

And it is going to be a lot bigger behind the scenes
that just adding up the bits.  You really do not need
to know the behind the scene details anyway.  Raku
strives to remove the need for the programmer to
have to know these kind of details, unlike C.

What system call are you trying to run?

I have an example of how to read Windows Time
that also uses OOP (class, object, and method).
Let me know if you want it

-T





Re: NativeCall -- size of data structure

2021-01-02 Thread Paul Procacci
Apologies.  I just came across it.

nativesizeof is the subroutine you're looking for.

Again, sorry for the noise.

~Paul


On Sat, Jan 2, 2021 at 7:58 PM Paul Procacci  wrote:

> Hey Gents,
>
> Hopefully a simple question that I could not find the answer to.
>
> Given the following:
>
> class PROCESSENTRY32 is repr('CStruct') {
> has int32 $.dwSize;
> has int32 $.cntUsage;
> has int32 $.th32ProcessID;
> has Pointer $.th32DefaultHeapID;
> has int32 $.th32ModuleID;
> has int32 $.cntThreads;
> has int32 $.th32ParentProcessID;
> has long $.pcPriClassBase;
> has int32 $.dwFlags;
> HAS Str @.szExeFile[260] is CArray;  # MAX_PATH on windows is 260
> };
>
>
> ... is there is a raku method that gives me the size of this data
> structure?
>
> In C for example one would use sizeof() to provide the size.  In raku I
> could not find the documentation that would provide this information.
>
> Thanks,
> Paul Procacci
> --
> __
>
> :(){ :|:& };:
>


-- 
__

:(){ :|:& };:


NativeCall -- size of data structure

2021-01-02 Thread Paul Procacci
Hey Gents,

Hopefully a simple question that I could not find the answer to.

Given the following:

class PROCESSENTRY32 is repr('CStruct') {
has int32 $.dwSize;
has int32 $.cntUsage;
has int32 $.th32ProcessID;
has Pointer $.th32DefaultHeapID;
has int32 $.th32ModuleID;
has int32 $.cntThreads;
has int32 $.th32ParentProcessID;
has long $.pcPriClassBase;
has int32 $.dwFlags;
HAS Str @.szExeFile[260] is CArray;  # MAX_PATH on windows is 260
};


... is there is a raku method that gives me the size of this data structure?

In C for example one would use sizeof() to provide the size.  In raku I
could not find the documentation that would provide this information.

Thanks,
Paul Procacci
-- 
__

:(){ :|:& };:


Re: for and ^ question

2021-01-02 Thread ToddAndMargo via perl6-users

On 1/1/21 10:47 PM, Patrick R. Michaud wrote:

On Fri, Jan 01, 2021 at 05:41:04PM -0800, ToddAndMargo via perl6-users wrote:

On 1/1/21 6:32 AM, David Santiago wrote:

say $_ for {0.1+$_}...^5


Is there a way to do this without the finger wagging?

say $_ for {0.1+$_}...^2


If you're going to a sequence operator ("...") instead of a range operator 
(".."), then you can specify the increment this way and it may be more readable:

> say $_ for 0.1, 0.2 ...^ 2;

Raku will auto-deduce the sequence from the values in the list on the LHS of 
the sequence operator:

> say $_ for 0.6, 1.1 ...^ 10;

This can be of course extended -- to count from $a up to $b in steps of $x, one 
can write:

> say $_ for $a, $a+$x ...^ $b

Note that in these examples the caret is part of the sequence operator, it's 
not a prefix to the $b argument.

Pm



Hi Patrick,

Awesome explanation.   I have added the following
to my notes on "for" loops.

Anyone want to see the whole "for" notes, let me know
with a "ping Todd" on the subject line

-T



Looping using an rational (Rat, 0.45) and floating point
(Num, 0.45e0) (also avoids having to use a C loop):

   Notes: it needs two points to know the iteration value
  and an end point.

  the tripple dots

  the ^ immediately after three third dot

   # loop from 0.0 to just before 2.0 by 0.3
   > say $_ for 0.0, 0.3 ...^2.0;
   0
   0.3
   0.6
   0.9
   1.2
   1.5
   1.8

   # loop from 0.0e0 to just before 2.0e0 by 0.3e0
   > say $_ for 0.0e0, 0.3e0 ...^2e0;
   0
   0.3
   0.6
   0.8999   # chuckle!
   1.2
   1.5
   1.8


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



Re: concurrency of asynchronous events - input from multiple keyboards

2021-01-02 Thread Nathan Gray
On Fri, Jan 01, 2021 at 03:20:09PM -0500, Vadim Belman wrote:
> As it seems that Audio::PortMIDI lacks non-blocking interface, I think a 
> solution would be to read events in a dedicated thread and re-submit them 
> into a Supplier. Something like:
> 
> my Supplier $midi-events;
> 
> start {
> loop {
> my $ev = $midi.read;
> $midi-events.emit: $ev;
> }
> }
> 
> 
> $midi-events can then be used in your react block. BTW, I think calling 
> method 'poll' must not be needed because `read` should block until actual 
> event is available. At least this is how I understand the normal order of 
> things.

Vadim,

Thank you for your reply.  I tried out not calling $midi.poll,
but found that $midi.read would return undef events (rather than
blocking until it received an event).  So I added it back in.
Thank you for the example of how to set up a supply.


On Fri, Jan 01, 2021 at 02:51:57PM -0600, Brad Gilbert wrote:
> I think the simplest way to turn that into a Supply is to use the `supply`
> keyword
> 
> my $pm = Audio::PortMIDI.new;
> 
> 
> my $input = supply {
> my $stream = $pm.open-input($input-device-number, 32);
> 
> DONE {
> $stream.close;
> }
> 
> loop {
> emit $stream.read(1);
> }
> }
> 
> 
> react {
> whenever key-pressed(:!echo) {
> given .fc {
> when 'q' { done }
> default { .raku.say }
> }
> }
> 
> my $voice = $pm.open-output($output-device-number, 32);
> whenever $input {
> $voice.write(|$_);
> }
> }

Brad,

Thank you for your reply.  I was able to get my code working
thanks to the examples from you and Vadim.

Here is what I ended up with:

my $pm = Audio::PortMIDI.new;

# Set up supply to read MIDI events.
my $input = supply {
my $stream = $pm.open-input($input-device-number, 32);

LAST {
$stream.close;
}

loop {
emit $stream.read(1) if $stream.poll;
}
}

# Set up handle to send MIDI events to the synthesizer.
my $voice = $pm.open-output($output-device-number, 32);

react {
# Read key presses from the computer keyboard.
# TODO: change $voice as needed based on computer keyboard input.
whenever key-pressed(:!echo) {
given .fc {
when 'q' { done }
default { .raku.say }
}
}

# Read MIDI events and send to the synthesizer.
whenever $input {
$voice.write(|$_);
}
}

-kolibrie


signature.asc
Description: PGP signature