1FFI::Platypus::Lang::WiUns3e2r(3C)ontributed Perl DocumeFnFtIa:t:iPolnatypus::Lang::Win32(3)
2
3
4
6 FFI::Platypus::Lang::Win32 - Documentation and tools for using Platypus
7 with the Windows API
8
10 version 1.43
11
13 use utf8;
14 use FFI::Platypus 1.35;
15
16 my $ffi = FFI::Platypus->new(
17 api => 1,
18 lib => [undef],
19 );
20
21 # load this plugin
22 $ffi->lang('Win32');
23
24 # Pass two double word integer values to the Windows API Beep function.
25 $ffi->attach( Beep => ['DWORD','DWORD'] => 'BOOL');
26 Beep(262, 300);
27
28 # Send a Unicode string to the Windows API MessageBoxW function.
29 use constant MB_OK => 0x00000000;
30 use constant MB_DEFAULT_DESKTOP_ONLY => 0x00020000;
31 $ffi->attach( [MessageBoxW => 'MessageBox'] => [ 'HWND', 'LPCWSTR', 'LPCWSTR', 'UINT'] => 'int' );
32 MessageBox(undef, "I ❤️ Platypus", "Confession", MB_OK|MB_DEFAULT_DESKTOP_ONLY);
33
34 # Get a Unicode string from the Windows API GetCurrentDirectoryW function.
35 $ffi->attach( [GetCurrentDirectoryW => 'GetCurrentDirectory'] => ['DWORD', 'LPWSTR'] => 'DWORD');
36 my $buf_size = GetCurrentDirectory(0,undef);
37 my $dir = "\0\0" x $buf_size;
38 GetCurrentDirectory($buf_size, \$dir) or die $^E;
39 print "$dir\n";
40
42 This module provides the Windows datatypes used by the Windows API.
43 This means that you can use things like "DWORD" as an alias for
44 "uint32". The full list of type aliases is not documented here as it
45 may change over time or be dynamic. You can get the list for your
46 current environment with this one-liner:
47
48 perl -MFFI::Platypus::Lang::Win32 -E "say for sort keys %{ FFI::Platypus::Lang::Win32->native_type_map }"
49
50 This plugin will also set the correct ABI for use with Win32 API
51 functions. (On 32 bit systems a different ABI is used for Win32 API
52 than what is used by the C library, on 32 bit systems the same ABI is
53 used). Most of the time this exactly what you want, but if you need to
54 use functions that are using the standard C calling convention, but
55 need the Win32 types, you can do that by setting the ABI back
56 immediately after loading the language plugin:
57
58 $ffi->lang('Win32');
59 $ffi->abi('default_abi');
60
61 Most of the types should be pretty self-explanatory or at least
62 provided in the Microsoft documentation on the internet, but the use of
63 Unicode strings probably requires some more detail:
64
65 [version 1.35]
66
67 This plugin also provides "LPCWSTR" and "LPWSTR" "wide" string types
68 which are implemented using FFI::Platypus::Type::WideString. For full
69 details, please see the documentation for that module, and note that
70 "LPCWSTR" is a wide string in the read-only string mode and "LPWSTR" is
71 a wide string in the read-write buffer mode.
72
73 The "LPCWSTR" is handled fairly transparently by the plugin, but for
74 when using read-write buffers ("LPWSTR") with the Win32 API you
75 typically need to allocate a buffer string of the right size. These
76 examples will use "GetCurrentDirectoryW" attached as
77 "GetCurrentDirectory" as in the synopsis above. These are illustrative
78 only, you would normally want to use the Cwd module to get the current
79 working directory.
80
81 default buffer size 2048
82 The simplest way is to fallback on the rather arbitrary default
83 buffer size of 2048.
84
85 my $dir;
86 GetCurrentDirectory(1024, \$dir);
87 print "I am in the directory: $dir\n";
88
89 Discussion: This only works if you know the API that you are using
90 will not ever use more than 2048 bytes. The author believes this
91 to be the case for "GetCurrentDirectoryW" since directory paths in
92 windows have a maximum of 260 characters. If every character was
93 outside the Basic Multilingual Plane (BMP) they would take up
94 exactly 4 characters each. (This is probably not ever the case
95 since the disk volume at least will be a Latin letter). Taking
96 account of the "NULL" termination you would need 260 * 4 + 2 bytes
97 or 1048 bytes.
98
99 We pass in a reference to our scalar so that the Win32 API can
100 write into it.
101
102 We are passing in half the number of bytes as the first argument
103 because the API expects the number of "WCHAR" (or "wchar_t"), not
104 the number of bytes or the technically the number of characters
105 since characters can take up either 2 or 4 bytes in UTF-16.
106
107 allocate your buffer to your own size.
108 If possible it is of course always best to allocate exactly the
109 size of buffer that you need.
110
111 my $size = GetCurrentDirectory(0, undef);
112 my $dir = "\0\0" x $size;
113 GetCurrentDirectory($size, \$dir);
114 print "I am in the directory: $dir\n";
115
116 Discussion: In this case the API provides a way of getting the
117 exact size of buffer that you need. We allocate this in Perl by
118 creating a string of "NULLs" of the right length. The Perl string
119 "\0" is exactly on byte, so we double that before using the "x"
120 operator to multiple that by the size returned by the API.
121
122 Now, somewhat unexpectedly what is returned is not the same buffer,
123 but a new string in new UTF-8 encoded Perl string. This is what
124 you want most of the time.
125
126 initialize your read-write buffer
127 Some APIs might be modifying an existing string rather than just
128 writing an entirely new one. In that case you still want to
129 allocate a buffer, but you want to initialize it with a value. You
130 can do this by passing an array reference instead of a scalar
131 reference. The firs element of the array is the buffer, and the
132 second is the initialization.
133
134 my $dir;
135 GetCurrentDirectory($size, [ \$dir, "I ❤ Perl + Platypus" ]);
136
137 Discussion: Note that this particular API ignores the string passed
138 in and writes over it, but this demonstrates how you would
139 initialize a buffer string. Once again, if $dir is not initialized
140 (is "undef"), then a buffer of the default size of 2048 bytes will
141 be created internally. You can also allocate a specific number of
142 bytes as in the previous example.
143
144 allocate memory using "malloc" etc.
145 You can also allocate memory using "malloc" (see
146 FFI::Platypus::Memory) and encode your string using Encode and copy
147 it using "wcscpy". This may be appropriate in some cases, but it
148 is beyond the scope of this document.
149
151 abi
152 my $abi = FFI::Platypus::Lang::Win32->abi;
153
154 This is called internally when the type plugin is loaded by Platypus.
155 It selects the appropriate ABI to make Win32 API function calls.
156
157 native_type_map
158 my $hashref = FFI::Platypus::Lang::Win32->native_type_map;
159
160 This is called internally when the type plugin is loaded by Platypus.
161 It provides types aliases useful on the Windows platform, so it may
162 also be useful for introspection.
163
164 This returns a hash reference containing the native aliases for the
165 Windows API. That is the keys are native Windows API C types and the
166 values are libffi native types.
167
168 This will includes types like "DWORD" and "HWND", and others. The full
169 list may be adjusted over time and may be computed dynamically. To get
170 the full list for your install you can use this one-liner:
171
172 perl -MFFI::Platypus::Lang::Win32 -E "say for sort keys %{ FFI::Platypus::Lang::Win32->native_type_map }"
173
174 load_custom_types
175 FFI::Platypus::Lang::Win32->load_custom_types($ffi);
176
177 This is called internally when the type plugin is loaded by Platypus.
178 It provides custom types useful on the Windows platform. For now that
179 means the "LPWSTR" and "LPCWSTR" types.
180
182 The Win32 API isn't a different computer language in the same sense
183 that the other language plugins (those for Fortran or Rust for
184 example). But implementing these types as a language plugin is the
185 most convenient way to do it.
186
187 Prior to version 1.35, this plugin didn't provide an implementation for
188 "LPWSTR" or "LPCWSTR", so in the likely event that you need those types
189 make sure you also require at least that version of Platypus.
190
192 FFI::Platypus
193 The Core Platypus documentation.
194
195 FFI::Platypus::Lang
196 Includes a list of other language plugins for Platypus.
197
198 FFI::Platypus::Type::WideString
199 The wide string type plugin use for "LPWSTR" and "LPCWSTR" types.
200
201 Win32::API
202 Another FFI, but for Windows only.
203
205 Author: Graham Ollis <plicease@cpan.org>
206
207 Contributors:
208
209 Bakkiaraj Murugesan (bakkiaraj)
210
211 Dylan Cali (calid)
212
213 pipcet
214
215 Zaki Mughal (zmughal)
216
217 Fitz Elliott (felliott)
218
219 Vickenty Fesunov (vyf)
220
221 Gregor Herrmann (gregoa)
222
223 Shlomi Fish (shlomif)
224
225 Damyan Ivanov
226
227 Ilya Pavlov (Ilya33)
228
229 Petr Pisar (ppisar)
230
231 Mohammad S Anwar (MANWAR)
232
233 Håkon Hægland (hakonhagland, HAKONH)
234
235 Meredith (merrilymeredith, MHOWARD)
236
237 Diab Jerius (DJERIUS)
238
239 Eric Brine (IKEGAMI)
240
241 szTheory
242
244 This software is copyright (c) 2015,2016,2017,2018,2019,2020 by Graham
245 Ollis.
246
247 This is free software; you can redistribute it and/or modify it under
248 the same terms as the Perl 5 programming language system itself.
249
250
251
252perl v5.32.1 2021-03-18 FFI::Platypus::Lang::Win32(3)