7

I would like to use the ncurses int addwstr(const wchar_t *wstr); function in Perl6.

How could I get a Perl 6 signatures which conveys const wchar_t *wstr of addwstr?

use v6;
use NativeCall;

constant LIB = 'libncursesw.so.5';

sub addwstr(  ?  ) returns int32 is native(LIB) is export {*};
brian d foy
  • 129,424
  • 31
  • 207
  • 592
sid_com
  • 24,137
  • 26
  • 96
  • 187
  • If I'm not mistaken it would be `Str is encoded('utf32')` on linux. – ElderBug Mar 04 '16 at 13:58
  • ElderBug: This gives me: "Unknown string encoding for native call: utf32 in ..." (on linux). – sid_com Mar 04 '16 at 14:50
  • I'm not really a perl guy so I'm not sure. `wchar_t` on linux is UTF-32. Maybe it will work with `'UTF-32'` ? – ElderBug Mar 04 '16 at 15:24
  • Reading `NativeCall.pm6` it looks like the utf32 encoding is not recognized by the native call engine. – sid_com Mar 04 '16 at 16:15
  • Seems like it's a dead end. Does it work for you if you use `addstr` instead of `addwstr`, with `Str is encoded('utf8')` ? Or maybe you could convert yourself to UTF-32 in perl, then pass to `addwstr` as an array of `int32`. – ElderBug Mar 04 '16 at 16:28
  • With `Str is encoded('utf8')` I still don't get the right output and when I try it with an array I get an error: `This representation (CArray) cannot unbox to a native string` – sid_com Mar 04 '16 at 17:35
  • Did you use `addstr` with utf8 ? I think you have to link `libncurses` instead of `libncursesw`. About the array, how does it knows the native expect a string ? Did you provide the signature somewhere ? I don't think it can read that from the '.so'. You should provide more details (maybe someone else could help you faster, but as for me, I need details). Also, add the attempts you did in the question (easier to follow for me and others who might help). – ElderBug Mar 04 '16 at 18:11
  • Maybe I understood what you did for the array. Did you properly put the definition as `sub addwstr( CArray[int32] )` ? Also, if you did the conversion yourself, make sure there is a terminal 0 at the end of the array (idk if perl do that already for its strings). – ElderBug Mar 04 '16 at 18:25
  • If you know a way to make this work, could you please post it as an answer. – sid_com Mar 05 '16 at 06:37
  • I don't know for now. You should add your tries to the question, because I'm not sure what you actually tried, so I don't really know what really doesn't work. Add some code where you use the function too. – ElderBug Mar 05 '16 at 13:42

1 Answers1

2

wchar_t is 32 bits on my machine. From the NativeCall doco, you can declare an array of them and the array name will act as the pointer;

#!/usr/bin/env perl6
use v6;
use NCurses;                   # To get iniscr(), endwin() etc
use NativeCall;

# Need to run setlocale from the C library
my int32 constant LC_ALL = 6;           # From locale.h
my sub setlocale(int32, Str) returns Str is native(Str) { * }

constant LIB = 'libncursesw.so.5';
sub addwstr(CArray[int32]) returns int32 is native(LIB) { * }

# The smiley        : Codepoint 0x263a
# Latin space       : Codepoint 0x20  (Ascii decimal ord 32)
# Check mark (tick) : Codepoint 0x2713

my CArray[int32] $wchar_str .= new(0x263a, 0x20, 0x2713);

setlocale(LC_ALL, "");
initscr();
move(2,2);
addwstr( $wchar_str );
nc_refresh;
while getch() < 0 {};
endwin;

This prints "☺ ✓" on my machine. It doesn't work without the call to setlocale.

As an aside, you don't have to use the 'w' functions - you can just pass normal perl6 strings (presumably encoded UTF-8) and it just works. This produces the same result;

#!/usr/bin/env perl6
use v6;
use NCurses;
use NativeCall;

# Need to run setlocale from the standard C library
my int32 constant LC_ALL = 6;           # From locale.h
my sub setlocale(int32, Str) returns Str is native(Str) { * }

my $ordinary_scalar = "☺ ✓";

setlocale(LC_ALL, "");
initscr();
move(2,2);
addstr( $ordinary_scalar );   # No 'w' necessary
nc_refresh;
while getch() < 0 {};
endwin;
Marty
  • 2,788
  • 11
  • 17
  • I don't think this is portable. On Windows, `wchar_t` is a `uint16` according to https://learn.microsoft.com/en-us/windows/desktop/midl/wchar-t – Kaiepi Aug 08 '18 at 07:40