1FFI::Platypus::Type::WiUdseeSrtrCionngt(r3i)buted Perl DFoFcIu:m:ePnltaattyipouns::Type::WideString(3)
2
3
4
6 FFI::Platypus::Type::WideString - Platypus custom type for Unicode
7 "wide" strings
8
10 version 2.08
11
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
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
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
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
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)