1FFI::Platypus::Type::WiUdseeSrtrCionngt(r3i)buted Perl DFoFcIu:m:ePnltaattyipouns::Type::WideString(3)
2
3
4

NAME

6       FFI::Platypus::Type::WideString - Platypus custom type for Unicode
7       "wide" strings
8

VERSION

10       version 2.08
11

SYNOPSIS

13        use FFI::Platypus 2.00;
14
15        my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
16        $ffi->load_custom_type('::WideString' => 'wstring', access => 'read' );
17        $ffi->load_custom_type('::WideString' => 'wstring_w', access => 'write' );
18
19        # call function that takes a constant wide string
20        $ffi->attach( wcscmp => ['wstring', 'wstring'] => 'int' );
21        my $diff = wcscmp("I ❤ perl + Platypus", "I ❤ perl + Platypus"); # returns 0
22
23        # call a function that takes a wide string for writing
24        $ffi->attach( wcscpy => ['wstring_w', 'wstring'] );
25        my $buf;
26        wcscpy(\$buf, "I ❤ perl + Platypus");
27        print $buf, "\n";  # prints "I ❤ perl + Platypus"
28
29        # call a function that takes a wide string for modification
30        $ffi->attach( wcscat => ['wstring_w', 'wstring'] );
31        my $buf;
32        wcscat( [ \$buf, "I ❤ perl" ], " + Platypus");
33        print $buf, "\n";  # prints "I ❤ perl + Platypus"
34
35       On Windows use with "LPCWSTR":
36
37        use FFI::Platypus 2.00;
38
39        my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
40
41        # define some custom Win32 Types
42        # to get these automatically see FFI::Platypus::Lang::Win32
43        $ffi->load_custom_type('::WideString' => 'LPCWSTR', access => 'read' );
44        $ffi->type('opaque' => 'HWND');
45        $ffi->type('uint'   => 'UINT');
46
47        use constant MB_OK                   => 0x00000000;
48        use constant MB_DEFAULT_DESKTOP_ONLY => 0x00020000;
49
50        $ffi->attach( [MessageBoxW => 'MessageBox'] => [ 'HWND', 'LPCWSTR', 'LPCWSTR', 'UINT'] => 'int' );
51
52        MessageBox(undef, "I ❤️ Platypus", "Confession", MB_OK|MB_DEFAULT_DESKTOP_ONLY);
53

DESCRIPTION

55       This custom type plugin for FFI::Platypus provides support for the
56       native "wide" string type on your platform, if it is available.
57
58       Wide strings are made of up wide characters ("wchar_t", also known as
59       "WCHAR" on Windows) and have enough bits to represent character sets
60       that require larger than the traditional one byte "char".
61
62       These strings are most commonly used on Windows where they are referred
63       to as "LPWSTR" and "LPCWSTR" (The former for read/write buffers and the
64       latter for const read-only strings), where they are encoded as
65       "UTF-16LE".
66
67       They are also supported by libc on many modern Unix systems where they
68       are usually "UTF-32" of the native byte-order of the system.  APIs on
69       Unix systems more commonly use UTF-8 which provides some compatibility
70       with ASCII, but you may occasionally find APIs that talk in wide
71       strings.  (libarchive, for example, can work in both).
72
73       This plugin will detect the native wide string format for you and
74       transparently convert Perl strings, which are typically encoded
75       internally as UTF-8.  If for some reason it cannot detect the correct
76       encoding, or if your platform is currently supported, an exception will
77       be thrown (please open a ticket if this is the case).  It can be used
78       either for read/write buffers, for const read-only strings, and for
79       return values.  It supports these options:
80
81       Options:
82
83       access
84           Either "read" or "write" depending on if you are using a read/write
85           buffer or a const read-only string.
86
87       size
88           For read/write buffer, the size of the buffer to create, if not
89           provided by the caller.
90
91   read-only
92       Read-only strings are the easiest of all, are converted to the native
93       wide string format in a buffer and are freed after that function call
94       completes.
95
96        $ffi->load_custom_type('::WideString' => 'wstring' );
97        $ffi->function( wprintf => [ 'wstring' ] => [ 'wstring' ] => 'int' )
98             ->call("I %s perl + Platypus", "❤");
99
100       This is the mode that you want to use when you are calling a function
101       that takes a "const wchar_t*" or a "LPCWSTR".
102
103   return value
104       For return values the "access" and "size" options are ignored.  The
105       string is simply copied into a Perl native string.
106
107        $ffi->load_custom_type('::WideString' => 'wstring' );
108        # see note below in CAVEATS about wcsdup
109        my $str = $ffi->function( wcsdup => [ 'wstring' ] => 'wstring' )
110                      ->call("I ❤ perl + Platypus");
111
112       This is the mode that you want to use when you are calling a function
113       that returns a "const wchar_t*", "wchar_t", "LPWSTR" or "LPCWSTR".
114
115   read/write
116       Read/write strings can be passed in one of two ways.  Which you choose
117       depends on if you want to initialize the read/write buffer or not.
118
119       default buffer size
120           The simplest way is to fallback on the default buffer size, which
121           can be specified using the "size" option when creating the custom
122           type.
123
124            my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
125            $ffi->load_custom_type('::WideString' => 'wstring',   access => 'read' );
126            $ffi->load_custom_type('::WideString' => 'wstring_w', access => 'write', size => 512 );
127
128            $ffi->attach( wcscpy => ['wstring_w', 'wstring'] );
129            my $buf;
130            wcscpy(\$buf, "I ❤ perl + Platypus");
131            print $buf, "\n";  # prints "I ❤ perl + Platypus"
132
133           Discussion: This is the most sensical approach when the exact size
134           of the buffer is known for all usages of the string type.  It can
135           also be sensical if the buffer size is larger than any possible
136           output, though care should be taken since this may be hard to
137           determine reliably.
138
139           The default size if none is specified when creating the custom type
140           is 2048, which is probably large enough for many uses, but also
141           probably wastes memory for many of them.
142
143       allocate your buffer of a specific size
144           The safest and most memory efficient method is of course to
145           allocate exactly the amount of memory that you need.
146
147            my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
148            $ffi->load_custom_type('::WideString' => 'wstring',   access => 'read'  );
149            $ffi->load_custom_type('::WideString' => 'wstring_w', access => 'write' );
150
151            $ffi->attach( wcscpy => ['wstring_w', 'wstring'] );
152            my $width = $ffi->sizeof('wchar_t');
153            my $buf = "\0" x ( (length ("I ❤ perl + Platypus") + 1)*$width);
154            wcscpy(\$buf, "I ❤ perl + Platypus");
155            print $buf, "\n";  # prints "I ❤ perl + Platypus"
156
157           Discussion: By assigning $buf to a string of null characters the
158           length of the source string, plus one (for the null at the end) and
159           then multiplying that by the size of "wchar_t", you get the exact
160           number of bytes needed for the destination buffer.
161
162           Note that although we pass in a reference to a buffer, what comes
163           back is converted to a Perl string, which will be internally UTF-8,
164           not stored at the original buffer location.  This is slightly
165           awkward, but what you need most of the time.
166
167       initialize the read/write buffer
168           Some functions don't expect empty null padded buffers though, in
169           this case you will want to initialize the buffer.
170
171            my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
172            $ffi->load_custom_type('::WideString' => 'wstring',   access => 'read'  );
173            $ffi->load_custom_type('::WideString' => 'wstring_w', access => 'write' );
174
175            $ffi->attach( wcscat => ['wstring_w', 'wstring'] );
176            my $buf;
177            wcscat( [ \$buf, "I ❤ perl" ], " + Platypus");
178            print $buf, "\n";  # prints "I ❤ perl + Platypus"
179
180           Discussion: To initialize we pass in an array reference instead of
181           a scalar reference.  The first element is a scalar reference to the
182           buffer (which can be pre-allocated or not; if it is not allocated
183           then it will be allocated to the default size for the type).  The
184           second argument is what the buffer should be initialized to before
185           the underlying C function is called.  The Perl string is encoded
186           into wide string format before being used to initialize the buffer.
187
188           As before a reference to the translated string is returned, and the
189           buffer that was used to pass in is freed.
190
191       allocate memory using "malloc" or "wcsdup" etc.
192           You can also allocate memory using "malloc" or "wcsdup" to return
193           an opaque type and manipulate it using the libc "wcs*" functions.
194           It will still probably be useful to use this plugin to cast the
195           opaque back to a Perl string.  The CAVEATS section below includes
196           several examples.
197
198       This is the mode that you want to use when you are calling a function
199       that takes a <wchar_t*> or a "LPWSTR".
200

CAVEATS

202       As with the Platypus built in "string" type, return values are copied
203       into a Perl scalar.  This is usually what you want anyway, but some
204       APIs expect the caller to take responsibility for freeing the pointer
205       to the wide string that it returns.  For example, "wcsdup" works in
206       this way.  The workaround is to return an opaque pointer, cast it from
207       a wide string and free the pointer.
208
209        use FFI::Platypus::Memory qw( free );
210        $ffi->load_custom_type('::WideString' => 'wstring' );
211        my $ptr = $ffi->function( wcsdup => [ 'wstring' ] => 'opaque' )
212                      ->call("I ❤ perl + Platypus");
213        my $str = $ffi->cast('opaque', 'wstring', $ptr);
214        free $ptr;
215
216       Because of the order in which objects are freed you cannot return a
217       wide string if it is also a wide string argument to a function.  For
218       example "wcscpy" may crash if you specify the return value as a wide
219       string:
220
221        # wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
222        $ffi->attach( wcscpy => [ 'wstring_w', 'wstring' ] => 'wstring' ); # no
223        my $str;
224        wcscpy( \$str, "I ❤ perl + Platypus");  # may crash on memory error
225
226       This is because the order in which things are done here are 1. $str is
227       allocated 2. $str is re-encoded as utf and the old buffer is freed 3.
228       the return value is computed based on the $str buffer that was freed.
229
230       If you look at "wcscpy" though you don't actually need the return
231       value.  To make this code work, you can just ignore the return value:
232
233        $ffi->attach( wcscpy => [ 'wstring_w', 'wstring' ] => 'void' ); # yes
234        my $str;
235        wcscpy( \$str, "I ❤ perl + Platypus"); # good!
236
237       On the other hand you do care about the return value from "wcschr",
238       which returns a pointer to the first occurrence of a character in an
239       argument string:
240
241        # wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
242        $ffi->attach( wcschr => [ 'wstring', 'wchar_t' ] => 'wstring' ); # no
243        # this may crash on memory error or return the wrong value
244        my $str = wcschr("I ❤ perl + Platypus", ord("❤"));
245
246       Instead you need to work with pointers and casts to use this function:
247
248        use FFI::Platypus 2.00;
249        use FFI::Platypus::Memory qw( free );
250
251        my $ffi = FFI::Platypus->new( api => 2, lib => [undef] );
252
253        $ffi->attach( wcsdup => ['wstring'] => 'opaque' );
254        $ffi->attach( strchr => [ opaque', 'wchar_t' ] => 'wstring' );
255
256        # create a wcs string in memory using wcsdup
257        my $haystack = wcsdup("I ❤ perl + Platypus");
258        # find the heart and return as a wide string
259        my $needle = strchr($haystack, ord("❤"));
260        # safe to free the pointer to the larger string now
261        free $haystack;
262

SEE ALSO

264       FFI::Platypus
265           Core Platypus documentation.
266
267       FFI::Platypus::Type
268           Includes documentation on handling "normal" 8 bit C strings among
269           others.
270
271       FFI::Platypus::Lang::Win32
272           Documentation for using Platypus with "LPWSTR" and "LPCWSTR" types
273           on Microsoft Windows.  These types are just aliases for the
274           standard C wide strings.
275

AUTHOR

277       Author: Graham Ollis <plicease@cpan.org>
278
279       Contributors:
280
281       Bakkiaraj Murugesan (bakkiaraj)
282
283       Dylan Cali (calid)
284
285       pipcet
286
287       Zaki Mughal (zmughal)
288
289       Fitz Elliott (felliott)
290
291       Vickenty Fesunov (vyf)
292
293       Gregor Herrmann (gregoa)
294
295       Shlomi Fish (shlomif)
296
297       Damyan Ivanov
298
299       Ilya Pavlov (Ilya33)
300
301       Petr Písař (ppisar)
302
303       Mohammad S Anwar (MANWAR)
304
305       Håkon Hægland (hakonhagland, HAKONH)
306
307       Meredith (merrilymeredith, MHOWARD)
308
309       Diab Jerius (DJERIUS)
310
311       Eric Brine (IKEGAMI)
312
313       szTheory
314
315       José Joaquín Atria (JJATRIA)
316
317       Pete Houston (openstrike, HOUSTON)
318
320       This software is copyright (c) 2015-2022 by Graham Ollis.
321
322       This is free software; you can redistribute it and/or modify it under
323       the same terms as the Perl 5 programming language system itself.
324
325
326
327perl v5.38.0                      2023-07-20FFI::Platypus::Type::WideString(3)
Impressum