FFI-Platypus
view release on metacpan or search on metacpan
lib/FFI/Platypus/Type/WideString.pm view on Meta::CPAN
use FFI::Platypus 2.00;
my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
$ffi->load_custom_type('::WideString' => 'wstring', access => 'read' );
$ffi->load_custom_type('::WideString' => 'wstring_w', access => 'write' );
# call function that takes a constant wide string
$ffi->attach( wcscmp => ['wstring', 'wstring'] => 'int' );
my $diff = wcscmp("I ⤠perl + Platypus", "I ⤠perl + Platypus"); # returns 0
# call a function that takes a wide string for writing
$ffi->attach( wcscpy => ['wstring_w', 'wstring'] );
my $buf;
wcscpy(\$buf, "I ⤠perl + Platypus");
print $buf, "\n"; # prints "I ⤠perl + Platypus"
# call a function that takes a wide string for modification
$ffi->attach( wcscat => ['wstring_w', 'wstring'] );
my $buf;
wcscat( [ \$buf, "I ⤠perl" ], " + Platypus");
print $buf, "\n"; # prints "I ⤠perl + Platypus"
On Windows use with C<LPCWSTR>:
use FFI::Platypus 2.00;
my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
# define some custom Win32 Types
# to get these automatically see FFI::Platypus::Lang::Win32
$ffi->load_custom_type('::WideString' => 'LPCWSTR', access => 'read' );
$ffi->type('opaque' => 'HWND');
$ffi->type('uint' => 'UINT');
use constant MB_OK => 0x00000000;
use constant MB_DEFAULT_DESKTOP_ONLY => 0x00020000;
$ffi->attach( [MessageBoxW => 'MessageBox'] => [ 'HWND', 'LPCWSTR', 'LPCWSTR', 'UINT'] => 'int' );
MessageBox(undef, "I â¤ï¸ Platypus", "Confession", MB_OK|MB_DEFAULT_DESKTOP_ONLY);
=head1 DESCRIPTION
This custom type plugin for L<FFI::Platypus> provides support for the native
"wide" string type on your platform, if it is available.
Wide strings are made of up wide characters (C<wchar_t>, also known as C<WCHAR>
on Windows) and have enough bits to represent character sets that require
larger than the traditional one byte C<char>.
These strings are most commonly used on Windows where they are referred to as
C<LPWSTR> and C<LPCWSTR> (The former for read/write buffers and the latter for
const read-only strings), where they are encoded as C<UTF-16LE>.
They are also supported by libc on many modern Unix systems where they are usually
C<UTF-32> of the native byte-order of the system. APIs on Unix systems more
commonly use UTF-8 which provides some compatibility with ASCII, but you may
occasionally find APIs that talk in wide strings. (libarchive, for example,
can work in both).
This plugin will detect the native wide string format for you and transparently
convert Perl strings, which are typically encoded internally as UTF-8. If for
some reason it cannot detect the correct encoding, or if your platform is
currently supported, an exception will be thrown (please open a ticket if this
is the case). It can be used either for read/write buffers, for const read-only
strings, and for return values. It supports these options:
Options:
=over 4
=item access
Either C<read> or C<write> depending on if you are using a read/write buffer
or a const read-only string.
=item size
For read/write buffer, the size of the buffer to create, if not provided by
the caller.
=back
=head2 read-only
Read-only strings are the easiest of all, are converted to the native wide
string format in a buffer and are freed after that function call completes.
$ffi->load_custom_type('::WideString' => 'wstring' );
$ffi->function( wprintf => [ 'wstring' ] => [ 'wstring' ] => 'int' )
->call("I %s perl + Platypus", "â¤");
This is the mode that you want to use when you are calling a function that
takes a C<const wchar_t*> or a C<LPCWSTR>.
=head2 return value
For return values the C<access> and C<size> options are ignored. The string
is simply copied into a Perl native string.
$ffi->load_custom_type('::WideString' => 'wstring' );
# see note below in CAVEATS about wcsdup
my $str = $ffi->function( wcsdup => [ 'wstring' ] => 'wstring' )
->call("I ⤠perl + Platypus");
This is the mode that you want to use when you are calling a function that
returns a C<const wchar_t*>, C<wchar_t>, C<LPWSTR> or C<LPCWSTR>.
=head2 read/write
Read/write strings can be passed in one of two ways. Which you choose
depends on if you want to initialize the read/write buffer or not.
=over 4
=item default buffer size
The simplest way is to fallback on the default buffer size, which can
be specified using the C<size> option when creating the custom type.
my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
( run in 0.795 second using v1.01-cache-2.11-cpan-302cb4679cc )