Codebase list libffi-platypus-perl / upstream/1.33
New upstream version 1.33 gregor herrmann 3 years ago
50 changed file(s) with 106 addition(s) and 807 deletion(s). Raw diff Collapse all Expand all
00 Revision history for FFI-Platypus
1
2 1.33 2020-09-28 10:47:26 -0600
3 - FFI::Platypus::Declare is no longer part of this distribution. It is
4 no available from FFI-Platypus-Declare instead. It has already
5 been discouraged for quite some time. (gh#285)
6 - Fix bug where bundled .so name could incorrectly get double colons (::)
7 in the name in development mode only. This is probably only a problem
8 on Windows. (gh#284)
19
210 1.32 2020-09-21 04:25:13 -0600
311 - Fix unsupported Perl tests.
152152 lib/FFI/Platypus/Closure.pm
153153 lib/FFI/Platypus/Constant.pm
154154 lib/FFI/Platypus/DL.pm
155 lib/FFI/Platypus/Declare.pm
156155 lib/FFI/Platypus/Function.pm
157156 lib/FFI/Platypus/Internal.pm
158157 lib/FFI/Platypus/Lang.pm
234233 t/ffi_platypus_bundle.t
235234 t/ffi_platypus_closure.t
236235 t/ffi_platypus_constant.t
237 t/ffi_platypus_declare.t
238236 t/ffi_platypus_dl.t
239237 t/ffi_platypus_function.t
240238 t/ffi_platypus_function_wrapper.t
8686 },
8787 "x_IRC" : "irc://irc.perl.org/#native"
8888 },
89 "version" : "1.32",
89 "version" : "1.33",
9090 "x_contributors" : [
9191 "Graham Ollis <plicease@cpan.org>",
9292 "Bakkiaraj Murugesan (bakkiaraj)",
105105 "Meredith (merrilymeredith, MHOWARD)",
106106 "Diab Jerius (DJERIUS)"
107107 ],
108 "x_generated_by_perl" : "v5.32.0",
108 "x_generated_by_perl" : "v5.33.0",
109109 "x_serialization_backend" : "Cpanel::JSON::XS version 4.19",
110110 "x_spdx_expression" : "Artistic-1.0-Perl OR GPL-1.0-or-later",
111111 "x_use_unsafe_inc" : 0
3636 bugtracker: https://github.com/PerlFFI/FFI-Platypus/issues
3737 homepage: https://metacpan.org/pod/FFI::Platypus
3838 repository: git://github.com/PerlFFI/FFI-Platypus.git
39 version: '1.32'
39 version: '1.33'
4040 x_contributors:
4141 - 'Graham Ollis <plicease@cpan.org>'
4242 - 'Bakkiaraj Murugesan (bakkiaraj)'
5454 - 'Håkon Hægland (hakonhagland, HAKONH)'
5555 - 'Meredith (merrilymeredith, MHOWARD)'
5656 - 'Diab Jerius (DJERIUS)'
57 x_generated_by_perl: v5.32.0
57 x_generated_by_perl: v5.33.0
5858 x_serialization_backend: 'YAML::Tiny version 1.73'
5959 x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later'
6060 x_use_unsafe_inc: 0
44 exit;
55 }
66 }
7 # This file was automatically generated by Dist::Zilla::Plugin::Author::Plicease::MakeMaker v2.56.
7 # This file was automatically generated by Dist::Zilla::Plugin::Author::Plicease::MakeMaker v2.57.
88 use strict;
99 use warnings;
1010 use 5.008004;
4343 "lib/FFI/Platypus/Closure.pm" => "\$(INST_LIB)/FFI/Platypus/Closure.pm",
4444 "lib/FFI/Platypus/Constant.pm" => "\$(INST_LIB)/FFI/Platypus/Constant.pm",
4545 "lib/FFI/Platypus/DL.pm" => "\$(INST_LIB)/FFI/Platypus/DL.pm",
46 "lib/FFI/Platypus/Declare.pm" => "\$(INST_LIB)/FFI/Platypus/Declare.pm",
4746 "lib/FFI/Platypus/Function.pm" => "\$(INST_LIB)/FFI/Platypus/Function.pm",
4847 "lib/FFI/Platypus/Internal.pm" => "\$(INST_LIB)/FFI/Platypus/Internal.pm",
4948 "lib/FFI/Platypus/Lang.pm" => "\$(INST_LIB)/FFI/Platypus/Lang.pm",
8281 "Capture::Tiny" => 0,
8382 "Test::More" => "0.98"
8483 },
85 "VERSION" => "1.32",
84 "VERSION" => "1.33",
8685 "test" => {
8786 "TESTS" => "t/*.t"
8887 }
44
55 VERSION
66
7 version 1.32
7 version 1.33
88
99 SYNOPSIS
1010
14331433 For more details on enumerated types see "Enum types" in
14341434 FFI::Platypus::Type.
14351435
1436 There is also a type plugin (FFI::Platypus::Type::Enum) that can be
1437 helpful in writing interfaces that use enums.
1438
14361439 Memory leaks
14371440
14381441 There are a couple places where memory is allocated, but never
22 license = Perl_5
33 copyright_holder = Graham Ollis
44 copyright_year = 2015,2016,2017,2018,2019,2020
5 version = 1.32
5 version = 1.33
66
77 ; authordep ExtUtils::MakeMaker
88
55
66 include/ppport.h -- Perl/Pollution/Portability Version 3.57
77
8 Automatically created by Devel::PPPort running under perl 5.032000.
8 Automatically created by Devel::PPPort running under perl 5.033000.
99
1010 Do NOT edit this file directly! -- Edit PPPort_pm.PL and the
1111 includes in parts/inc/ instead.
99 use overload '""' => sub { $_[0]->path }, bool => sub { 1 }, fallback => 1;
1010
1111 # ABSTRACT: Base class for File::Build files
12 our $VERSION = '1.32'; # VERSION
12 our $VERSION = '1.33'; # VERSION
1313
1414
1515 sub new
157157
158158 =head1 VERSION
159159
160 version 1.32
160 version 1.33
161161
162162 =head1 SYNOPSIS
163163
1010 use FFI::Build::File::Object;
1111
1212 # ABSTRACT: Class to track C source file in FFI::Build
13 our $VERSION = '1.32'; # VERSION
13 our $VERSION = '1.33'; # VERSION
1414
1515
1616 sub accept_suffix
185185
186186 =head1 VERSION
187187
188 version 1.32
188 version 1.33
189189
190190 =head1 SYNOPSIS
191191
77 use constant default_encoding => ':utf8';
88
99 # ABSTRACT: Class to track C source file in FFI::Build
10 our $VERSION = '1.32'; # VERSION
10 our $VERSION = '1.33'; # VERSION
1111
1212
1313 sub accept_suffix
4141
4242 =head1 VERSION
4343
44 version 1.32
44 version 1.33
4545
4646 =head1 SYNOPSIS
4747
66 use constant default_encoding => ':raw';
77
88 # ABSTRACT: Class to track object file in FFI::Build
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 sub default_suffix
2828
2929 =head1 VERSION
3030
31 version 1.32
31 version 1.33
3232
3333 =head1 SYNOPSIS
3434
77 use Carp ();
88
99 # ABSTRACT: Class to track object file in FFI::Build
10 our $VERSION = '1.32'; # VERSION
10 our $VERSION = '1.33'; # VERSION
1111
1212
1313 sub default_suffix
3939
4040 =head1 VERSION
4141
42 version 1.32
42 version 1.33
4343
4444 =head1 SYNOPSIS
4545
1212 use ExtUtils::MakeMaker 7.12;
1313
1414 # ABSTRACT: FFI::Build installer code for ExtUtils::MakeMaker
15 our $VERSION = '1.32'; # VERSION
15 our $VERSION = '1.33'; # VERSION
1616
1717
1818 sub new
307307
308308 =head1 VERSION
309309
310 version 1.32
310 version 1.33
311311
312312 =head1 SYNOPSIS
313313
1010 use FFI::Platypus::ShareConfig;
1111
1212 # ABSTRACT: Platform specific configuration.
13 our $VERSION = '1.32'; # VERSION
13 our $VERSION = '1.33'; # VERSION
1414
1515
1616 sub new
420420
421421 =head1 VERSION
422422
423 version 1.32
423 version 1.33
424424
425425 =head1 SYNOPSIS
426426
1111 use File::Path ();
1212
1313 # ABSTRACT: Build shared libraries for use with FFI
14 our $VERSION = '1.32'; # VERSION
14 our $VERSION = '1.33'; # VERSION
1515
1616
1717 sub _native_name
301301
302302 =head1 VERSION
303303
304 version 1.32
304 version 1.33
305305
306306 =head1 SYNOPSIS
307307
88 our @EXPORT = grep /^arguments_/, keys %FFI::Platypus::API::;
99
1010 # ABSTRACT: Platypus arguments and return value API for custom types
11 our $VERSION = '1.32'; # VERSION
11 our $VERSION = '1.33'; # VERSION
1212
1313
1414 1;
2525
2626 =head1 VERSION
2727
28 version 1.32
28 version 1.33
2929
3030 =head1 SYNOPSIS
3131
99 our @EXPORT_OK = qw ( scalar_to_pointer grow set_used_length window );
1010
1111 # ABSTRACT: Convert scalars to C buffers
12 our $VERSION = '1.32'; # VERSION
12 our $VERSION = '1.33'; # VERSION
1313
1414
1515 use constant _incantation =>
4949
5050 =head1 VERSION
5151
52 version 1.32
52 version 1.33
5353
5454 =head1 SYNOPSIS
5555
55 use Carp ();
66
77 # ABSTRACT: Bundle foreign code with your Perl module
8 our $VERSION = '1.32'; # VERSION
8 our $VERSION = '1.33'; # VERSION
99
1010
1111 package FFI::Platypus;
7979 my($output, $error) = Capture::Tiny::capture_merged(sub {
8080 $lib = eval {
8181 my $dist_name = $package;
82 $dist_name =~ s/::/-/;
82 $dist_name =~ s/::/-/g;
8383 my $fbmm = FFI::Build::MM->new( save => 0 );
8484 $fbmm->mm_args( DISTNAME => $dist_name );
8585 my $build = $fbmm->load_build('ffi', undef, 'ffi/_build');
149149
150150 =head1 VERSION
151151
152 version 1.32
152 version 1.33
153153
154154 =head1 SYNOPSIS
155155
1111 }, bool => sub { 1 }, fallback => 1;
1212
1313 # ABSTRACT: Platypus closure object
14 our $VERSION = '1.32'; # VERSION
14 our $VERSION = '1.33'; # VERSION
1515
1616
1717 sub new
6666
6767 package FFI::Platypus::ClosureData;
6868
69 our $VERSION = '1.32'; # VERSION
69 our $VERSION = '1.33'; # VERSION
7070
7171 1;
7272
8282
8383 =head1 VERSION
8484
85 version 1.32
85 version 1.33
8686
8787 =head1 SYNOPSIS
8888
66 use FFI::Platypus;
77
88 # ABSTRACT: Define constants in C space for Perl
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 {
6565
6666 =head1 VERSION
6767
68 version 1.32
68 version 1.33
6969
7070 =head1 SYNOPSIS
7171
99 push @EXPORT, grep /RTLD_/, keys %FFI::Platypus::DL::;
1010
1111 # ABSTRACT: Slightly non-portable interface to libdl
12 our $VERSION = '1.32'; # VERSION
12 our $VERSION = '1.33'; # VERSION
1313
1414
1515 1;
2626
2727 =head1 VERSION
2828
29 version 1.32
29 version 1.33
3030
3131 =head1 SYNOPSIS
3232
+0
-471
lib/FFI/Platypus/Declare.pm less more
0 package FFI::Platypus::Declare;
1
2 use strict;
3 use warnings;
4 use 5.008004;
5 use Carp ();
6 use FFI::Platypus;
7
8 # ABSTRACT: Declarative interface to FFI::Platypus
9 our $VERSION = '1.32'; # VERSION
10
11
12 our $ffi = {};
13 our $types = {};
14
15 sub _ffi_object
16 {
17 my($package, $filename) = caller(1);
18 $ffi->{$package} ||= FFI::Platypus->new->package($package,$filename);
19 }
20
21
22 sub lib (@)
23 {
24 _ffi_object->lib(@_);
25 }
26
27
28 sub type ($;$)
29 {
30 _ffi_object->type(@_);
31 }
32
33
34 sub custom_type ($$)
35 {
36 _ffi_object->custom_type(@_);
37 }
38
39
40 sub load_custom_type ($$;@)
41 {
42 _ffi_object->load_custom_type(@_);
43 }
44
45
46 sub type_meta($)
47 {
48 _ffi_object->type_meta(@_);
49 }
50
51
52 my $inner_counter = 0;
53
54 sub attach ($$$;$$)
55 {
56 my $wrapper;
57 $wrapper = pop if ref($_[-1]) eq 'CODE';
58 my($name, $args, $ret, $proto) = @_;
59
60 my($symbol_name, $perl_name) = ref $name ? (@$name) : ($name, $name);
61 my $function = _ffi_object->function($symbol_name, $args, $ret, $wrapper);
62 $function->attach($perl_name, $proto);
63 ();
64 }
65
66
67 sub closure (&)
68 {
69 my($coderef) = @_;
70 require FFI::Platypus::Closure;
71 FFI::Platypus::Closure->new($coderef);
72 }
73
74
75 sub sticky ($)
76 {
77 my($closure) = @_;
78 Carp::croak("usage: sticky \$closure")
79 unless defined $closure && ref($closure) eq 'FFI::Platypus::Closure';
80 $closure->sticky;
81 $closure;
82 }
83
84
85 sub cast ($$$)
86 {
87 _ffi_object->cast(@_);
88 }
89
90
91 sub attach_cast ($$$)
92 {
93 my($name, $type1, $type2) = @_;
94 my $caller = caller;
95 $name = join '::', $caller, $name;
96 _ffi_object->attach_cast($name, $type1, $type2);
97 }
98
99
100 sub sizeof ($)
101 {
102 _ffi_object->sizeof($_[0]);
103 }
104
105
106 sub lang ($)
107 {
108 _ffi_object->lang($_[0]);
109 }
110
111
112 sub abi ($)
113 {
114 _ffi_object->abi($_[0]);
115 }
116
117 sub import
118 {
119 my $caller = caller;
120 shift; # class
121
122 foreach my $arg (@_)
123 {
124 if(ref $arg)
125 {
126 if($arg->[0] =~ /::/)
127 {
128 _ffi_object->load_custom_type(@$arg);
129 no strict 'refs';
130 *{join '::', $caller, $arg->[1]} = sub () { $arg->[1] };
131 }
132 else
133 {
134 _ffi_object->type(@$arg);
135 no strict 'refs';
136 *{join '::', $caller, $arg->[1]} = sub () { $arg->[0] };
137 }
138 }
139 else
140 {
141 _ffi_object->type($arg);
142 no strict 'refs';
143 *{join '::', $caller, $arg} = sub () { $arg };
144 }
145 }
146
147 no strict 'refs';
148 *{join '::', $caller, 'lib'} = \&lib;
149 *{join '::', $caller, 'type'} = \&type;
150 *{join '::', $caller, 'type_meta'} = \&type_meta;
151 *{join '::', $caller, 'custom_type'} = \&custom_type;
152 *{join '::', $caller, 'load_custom_type'} = \&load_custom_type;
153 *{join '::', $caller, 'attach'} = \&attach;
154 *{join '::', $caller, 'closure'} = \&closure;
155 *{join '::', $caller, 'sticky'} = \&sticky;
156 *{join '::', $caller, 'cast'} = \&cast;
157 *{join '::', $caller, 'attach_cast'} = \&attach_cast;
158 *{join '::', $caller, 'sizeof'} = \&sizeof;
159 *{join '::', $caller, 'lang'} = \&lang;
160 *{join '::', $caller, 'abi'} = \&abi;
161 }
162
163 1;
164
165 __END__
166
167 =pod
168
169 =encoding UTF-8
170
171 =head1 NAME
172
173 FFI::Platypus::Declare - Declarative interface to FFI::Platypus
174
175 =head1 VERSION
176
177 version 1.32
178
179 =head1 SYNOPSIS
180
181 use FFI::Platypus::Declare 'string', 'int';
182
183 lib undef; # use libc
184 attach puts => [string] => int;
185
186 puts("hello world");
187
188 =head1 DESCRIPTION
189
190 This module is officially B<discouraged>. The idea was to provide a
191 simpler declarative interface without the need of (directly) creating
192 an L<FFI::Platypus> instance. In practice it is almost as complicated
193 and makes it difficult to upgrade to the proper OO interface if the
194 need arises. I have stopped using it mainly for this reason. It will
195 remain as part of the Platypus core distribution to keep old code working,
196 but you are encouraged to write new code using the OO interface.
197 Alternatively, you can try the Perl 6 inspired L<NativeCall>, which
198 provides most of the goals this module was intended for (that is
199 a simple interface at the cost of some power), without much of the
200 complexity. The remainder of this document describes the interface.
201
202 This module provides a declarative interface to L<FFI::Platypus>. It
203 provides a more concise interface at the cost of a little less power,
204 and a little more namespace pollution.
205
206 Any strings passed into the C<use> line will be declared as types and
207 exported as constants into your namespace, so that you can use them
208 without quotation marks.
209
210 Aliases can be declared using a list reference:
211
212 use FFI::Platypus [ 'int[48]' => 'my_integer_array' ];
213
214 Custom types can also be declared as a list reference (the type name
215 must include a ::):
216
217 use FFI::Platypus [ '::StringPointer' => 'my_string_pointer' ];
218 # short for FFI::Platypus::Type::StringPointer
219
220 =head1 FUNCTIONS
221
222 All functions are exported into your namespace. If you do not want that,
223 then use the OO interface (see L<FFI::Platypus>).
224
225 =head2 lib
226
227 lib $libpath;
228
229 Specify one or more dynamic libraries to search for symbols. If you are
230 unsure of the location / version of the library then you can use
231 L<FFI::CheckLib#find_lib>.
232
233 =head2 type
234
235 type $type;
236 type $type = $alias;
237
238 Declare the given type.
239
240 Examples:
241
242 type 'uint8'; # only really checks that uint8 is a valid type
243 type 'uint8' => 'my_unsigned_int_8';
244
245 =head2 custom_type
246
247 custom_type $alias => \%args;
248
249 Declare the given custom type. See L<FFI::Platypus::Type#Custom-Types>
250 for details.
251
252 =head2 load_custom_type
253
254 load_custom_type $name => $alias, @type_args;
255
256 Load the custom type defined in the module I<$name>, and make an alias
257 with the name I<$alias>. If the custom type requires any arguments, they
258 may be passed in as I<@type_args>. See L<FFI::Platypus::Type#Custom-Types>
259 for details.
260
261 If I<$name> contains C<::> then it will be assumed to be a fully
262 qualified package name. If not, then C<FFI::Platypus::Type::> will be
263 prepended to it.
264
265 =head2 type_meta
266
267 my $meta = type_meta $type;
268
269 Get the type meta data for the given type.
270
271 Example:
272
273 my $meta = type_meta 'int';
274
275 =head2 attach
276
277 attach $name => \@argument_types => $return_type;
278 attach [$c_name => $perl_name] => \@argument_types => $return_type;
279 attach [$address => $perl_name] => \@argument_types => $return_type;
280
281 Find and attach a C function as a Perl function as a real live xsub.
282
283 If just one I<$name> is given, then the function will be attached in
284 Perl with the same name as it has in C. The second form allows you to
285 give the Perl function a different name. You can also provide a memory
286 address (the third form) of a function to attach.
287
288 Examples:
289
290 attach 'my_function', ['uint8'] => 'string';
291 attach ['my_c_function_name' => 'my_perl_function_name'], ['uint8'] => 'string';
292 my $string1 = my_function($int);
293 my $string2 = my_perl_function_name($int);
294
295 =head2 closure
296
297 my $closure = closure $codeblock;
298
299 Create a closure that can be passed into a C function. For details on closures, see L<FFI::Platypus::Type#Closures>.
300
301 Example:
302
303 my $closure1 = closure { return $_[0] * 2 };
304 my $closure2 = closure sub { return $_[0] * 4 };
305
306 =head2 sticky
307
308 my $closure = sticky closure $codeblock;
309
310 Keyword to indicate the closure should not be deallocated for the life
311 of the current process.
312
313 If you pass a closure into a C function without saving a reference to it
314 like this:
315
316 foo(closure { ... }); # BAD
317
318 Perl will not see any references to it and try to free it immediately.
319 (this has to do with the way Perl and C handle responsibilities for
320 memory allocation differently). One fix for this is to make sure the
321 closure remains in scope using either C<my> or C<our>. If you know the
322 closure will need to remain in existence for the life of the process (or
323 if you do not care about leaking memory), then you can add the sticky
324 keyword to tell L<FFI::Platypus> to keep the thing in memory.
325
326 foo(sticky closure { ... }); # OKAY
327
328 =head2 cast
329
330 my $converted_value = cast $original_type, $converted_type, $original_value;
331
332 The C<cast> function converts an existing I<$original_value> of type
333 I<$original_type> into one of type I<$converted_type>. Not all types
334 are supported, so care must be taken. For example, to get the address
335 of a string, you can do this:
336
337 my $address = cast 'string' => 'opaque', $string_value;
338
339 =head2 attach_cast
340
341 attach_cast "cast_name", $original_type, $converted_type;
342 my $converted_value = cast_name($original_value);
343
344 This function creates a subroutine which can be used to convert
345 variables just like the L<cast|FFI::Platypus::Declare#cast> function
346 above. The above synopsis is roughly equivalent to this:
347
348 sub cast_name { cast($original_type, $converted_type, $_[0]) }
349 my $converted_value = cast_name($original_value);
350
351 Except that the L<attach_cast|FFI::Platypus::Declare#attach_cast>
352 variant will be much faster if called multiple times since the cast does
353 not need to be dynamically allocated on each instance.
354
355 =head2 sizeof
356
357 my $size = sizeof $type;
358
359 Returns the total size of the given type. For example to get the size
360 of an integer:
361
362 my $intsize = sizeof 'int'; # usually 4 or 8 depending on platform
363
364 You can also get the size of arrays
365
366 my $intarraysize = sizeof 'int[64]';
367
368 Keep in mind that "pointer" types will always be the pointer / word size
369 for the platform that you are using. This includes strings, opaque and
370 pointers to other types.
371
372 This function is not very fast, so you might want to save this value as
373 a constant, particularly if you need the size in a loop with many
374 iterations.
375
376 =head2 lang
377
378 lang $language;
379
380 Specifies the foreign language that you will be interfacing with. The
381 default is C. The foreign language specified with this attribute
382 changes the default native types (for example, if you specify
383 L<Rust|FFI::Platypus::Lang::Rust>, you will get C<i32> as an alias for
384 C<sint32> instead of C<int> as you do with L<C|FFI::Platypus::Lang::C>).
385
386 In the future this may attribute may offer hints when doing demangling
387 of languages that require it like L<C++|FFI::Platypus::Lang::CPP>.
388
389 =head2 abi
390
391 abi $abi;
392
393 Set the ABI or calling convention for use in subsequent calls
394 to L</attach>. May be either a string name or integer value
395 from L<FFI::Platypus#abis>.
396
397 =head1 SEE ALSO
398
399 =over 4
400
401 =item L<FFI::Platypus>
402
403 Object oriented interface to Platypus.
404
405 =item L<FFI::Platypus::Type>
406
407 Type definitions for Platypus.
408
409 =item L<FFI::Platypus::API>
410
411 Custom types API for Platypus.
412
413 =item L<FFI::Platypus::Memory>
414
415 memory functions for FFI.
416
417 =item L<FFI::CheckLib>
418
419 Find dynamic libraries in a portable way.
420
421 =item L<FFI::TinyCC>
422
423 JIT compiler for FFI.
424
425 =back
426
427 =head1 AUTHOR
428
429 Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
430
431 Contributors:
432
433 Bakkiaraj Murugesan (bakkiaraj)
434
435 Dylan Cali (calid)
436
437 pipcet
438
439 Zaki Mughal (zmughal)
440
441 Fitz Elliott (felliott)
442
443 Vickenty Fesunov (vyf)
444
445 Gregor Herrmann (gregoa)
446
447 Shlomi Fish (shlomif)
448
449 Damyan Ivanov
450
451 Ilya Pavlov (Ilya33)
452
453 Petr Pisar (ppisar)
454
455 Mohammad S Anwar (MANWAR)
456
457 Håkon Hægland (hakonhagland, HAKONH)
458
459 Meredith (merrilymeredith, MHOWARD)
460
461 Diab Jerius (DJERIUS)
462
463 =head1 COPYRIGHT AND LICENSE
464
465 This software is copyright (c) 2015,2016,2017,2018,2019,2020 by Graham Ollis.
466
467 This is free software; you can redistribute it and/or modify it under
468 the same terms as the Perl 5 programming language system itself.
469
470 =cut
55 use FFI::Platypus;
66
77 # ABSTRACT: An FFI function object
8 our $VERSION = '1.32'; # VERSION
8 our $VERSION = '1.33'; # VERSION
99
1010
1111 use overload '&{}' => sub {
126126
127127 =head1 VERSION
128128
129 version 1.32
129 version 1.33
130130
131131 =head1 SYNOPSIS
132132
1111 our @EXPORT = grep /^FFI_PL/, keys %FFI::Platypus::Internal::;
1212
1313 # ABSTRACT: For internal use only
14 our $VERSION = '1.32'; # VERSION
14 our $VERSION = '1.33'; # VERSION
1515
1616
1717 1;
2828
2929 =head1 VERSION
3030
31 version 1.32
31 version 1.33
3232
3333 =head1 SYNOPSIS
3434
44 use 5.008004;
55
66 # ABSTRACT: Documentation and tools for using Platypus with the Assembly
7 our $VERSION = '1.32'; # VERSION
7 our $VERSION = '1.33'; # VERSION
88
99
1010 sub native_type_map
2626
2727 =head1 VERSION
2828
29 version 1.32
29 version 1.33
3030
3131 =head1 SYNOPSIS
3232
44 use 5.008004;
55
66 # ABSTRACT: Documentation and tools for using Platypus with the C programming language
7 our $VERSION = '1.32'; # VERSION
7 our $VERSION = '1.33'; # VERSION
88
99
1010 sub native_type_map
2727
2828 =head1 VERSION
2929
30 version 1.32
30 version 1.33
3131
3232 =head1 SYNOPSIS
3333
55 use Config;
66
77 # ABSTRACT: Documentation and tools for using Platypus with the Windows API
8 our $VERSION = '1.32'; # VERSION
8 our $VERSION = '1.33'; # VERSION
99
1010
1111 sub abi
187187
188188 =head1 VERSION
189189
190 version 1.32
190 version 1.33
191191
192192 =head1 SYNOPSIS
193193
44 use 5.008004;
55
66 # ABSTRACT: Language specific customizations
7 our $VERSION = '1.32'; # VERSION
7 our $VERSION = '1.33'; # VERSION
88
99
1010
2222
2323 =head1 VERSION
2424
25 version 1.32
25 version 1.33
2626
2727 =head1 SYNOPSIS
2828
44 use 5.008004;
55
66 # ABSTRACT: Legacy Platypus interfaces
7 our $VERSION = '1.32'; # VERSION
7 our $VERSION = '1.33'; # VERSION
88
99
1010 package FFI::Platypus;
7777
7878 =head1 VERSION
7979
80 version 1.32
80 version 1.33
8181
8282 =head1 DESCRIPTION
8383
66 use base qw( Exporter );
77
88 # ABSTRACT: Memory functions for FFI
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 our @EXPORT = qw( malloc free calloc realloc memcpy memset strdup strndup strcpy );
6666
6767 =head1 VERSION
6868
69 version 1.32
69 version 1.33
7070
7171 =head1 SYNOPSIS
7272
44 use 5.008004;
55
66 # ABSTRACT: FFI support for structured records data
7 our $VERSION = '1.32'; # VERSION
7 our $VERSION = '1.33'; # VERSION
88
99
1010 {
8282
8383 =head1 VERSION
8484
85 version 1.32
85 version 1.33
8686
8787 =head1 DESCRIPTION
8888
55 use Carp qw( croak );
66
77 # ABSTRACT: Tied array interface for record array members
8 our $VERSION = '1.32'; # VERSION
8 our $VERSION = '1.33'; # VERSION
99
1010
1111 sub TIEARRAY
6262
6363 =head1 VERSION
6464
65 version 1.32
65 version 1.33
6666
6767 =head1 SYNOPSIS
6868
1010 our @EXPORT = qw( record_layout record_layout_1 );
1111
1212 # ABSTRACT: FFI support for structured records data
13 our $VERSION = '1.32'; # VERSION
13 our $VERSION = '1.33'; # VERSION
1414
1515
1616 sub record_layout_1
199199
200200 =head1 VERSION
201201
202 version 1.32
202 version 1.33
203203
204204 =head1 SYNOPSIS
205205
44 use 5.008004;
55 use File::Spec;
66
7 our $VERSION = '1.32'; # VERSION
7 our $VERSION = '1.33'; # VERSION
88
99 sub dist_dir ($)
1010 {
6363
6464 =head1 VERSION
6565
66 version 1.32
66 version 1.33
6767
6868 =head1 AUTHOR
6969
1212 use FFI::Platypus::Buffer qw( buffer_to_scalar );
1313
1414 # ABSTRACT: Convert string scalar to a buffer as a pointer / size_t combination
15 our $VERSION = '1.32'; # VERSION
15 our $VERSION = '1.33'; # VERSION
1616
1717
1818 my @stack;
6060
6161 =head1 VERSION
6262
63 version 1.32
63 version 1.33
6464
6565 =head1 SYNOPSIS
6666
55 use FFI::Platypus;
66
77 # ABSTRACT: Platypus custom type for arrays of strings
8 our $VERSION = '1.32'; # VERSION
8 our $VERSION = '1.33'; # VERSION
99
1010
1111 use constant _incantation =>
124124
125125 =head1 VERSION
126126
127 version 1.32
127 version 1.33
128128
129129 =head1 SYNOPSIS
130130
66 use Scalar::Util qw( readonly );
77
88 # ABSTRACT: Convert a pointer to a string and back
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 use constant _incantation =>
7575
7676 =head1 VERSION
7777
78 version 1.32
78 version 1.33
7979
8080 =head1 SYNOPSIS
8181
66 require FFI::Platypus;
77
88 # ABSTRACT: Defining types for FFI::Platypus
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111 # The TypeParser and Type classes are used internally ONLY and
1212 # are not to be exposed to the user. External users should
5757
5858 =head1 VERSION
5959
60 version 1.32
60 version 1.33
6161
6262 =head1 SYNOPSIS
6363
362362
363363 The main FAQ (L<FFI::Platypus/FAQ>) also has a discussion on dealing
364364 with constants and enumerated types.
365
366 There is also a type plugin (L<FFI::Platypus::Type::Enum>) that can be helpful
367 in writing interfaces that use enums.
365368
366369 =head3 Boolean types
367370
66 use base qw( FFI::Platypus::TypeParser );
77
88 # ABSTRACT: FFI Type Parser Version Zero
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 our @CARP_NOT = qw( FFI::Platypus FFI::Platypus::TypeParser );
164164
165165 =head1 VERSION
166166
167 version 1.32
167 version 1.33
168168
169169 =head1 SYNOPSIS
170170
66 use base qw( FFI::Platypus::TypeParser );
77
88 # ABSTRACT: FFI Type Parser Version One
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 our @CARP_NOT = qw( FFI::Platypus FFI::Platypus::TypeParser );
290290
291291 =head1 VERSION
292292
293 version 1.32
293 version 1.33
294294
295295 =head1 SYNOPSIS
296296
66 use Carp qw( croak );
77
88 # ABSTRACT: FFI Type Parser
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 # The TypeParser and Type classes are used internally ONLY and
111111
112112 =head1 VERSION
113113
114 version 1.32
114 version 1.33
115115
116116 =head1 DESCRIPTION
117117
77 use FFI::Platypus::Type;
88
99 # ABSTRACT: Write Perl bindings to non-Perl libraries with FFI. No XS required.
10 our $VERSION = '1.32'; # VERSION
10 our $VERSION = '1.33'; # VERSION
1111
1212 # Platypus Man,
1313 # Platypus Man,
582582
583583 =head1 VERSION
584584
585 version 1.32
585 version 1.33
586586
587587 =head1 SYNOPSIS
588588
20362036
20372037 For more details on enumerated types see L<FFI::Platypus::Type/"Enum types">.
20382038
2039 There is also a type plugin (L<FFI::Platypus::Type::Enum>) that can be helpful
2040 in writing interfaces that use enums.
2041
20392042 =head2 Memory leaks
20402043
20412044 There are a couple places where memory is allocated, but never deallocated that may
88 use FFI::Build::Platform;
99
1010 # ABSTRACT: Probe runner builder for FFI
11 our $VERSION = '1.32'; # VERSION
11 our $VERSION = '1.33'; # VERSION
1212
1313
1414 sub new
250250
251251 =head1 VERSION
252252
253 version 1.32
253 version 1.33
254254
255255 =head1 SYNOPSIS
256256
44 use 5.008004;
55
66 # ABSTRACT: The results from a probe run.
7 our $VERSION = '1.32'; # VERSION
7 our $VERSION = '1.33'; # VERSION
88
99
1010 sub new
4141
4242 =head1 VERSION
4343
44 version 1.32
44 version 1.33
4545
4646 =head1 SYNOPSIS
4747
66 use FFI::Probe::Runner::Result;
77
88 # ABSTRACT: Probe runner for FFI
9 our $VERSION = '1.32'; # VERSION
9 our $VERSION = '1.33'; # VERSION
1010
1111
1212 sub new
8484
8585 =head1 VERSION
8686
87 version 1.32
87 version 1.33
8888
8989 =head1 SYNOPSIS
9090
1111 use FFI::Temp;
1212
1313 # ABSTRACT: System detection and probing for FFI extensions.
14 our $VERSION = '1.32'; # VERSION
14 our $VERSION = '1.33'; # VERSION
1515
1616
1717 sub new
512512
513513 =head1 VERSION
514514
515 version 1.32
515 version 1.33
516516
517517 =head1 SYNOPSIS
518518
77 use File::Temp qw( tempdir );
88
99 # ABSTRACT: Temp Dir support for FFI::Platypus
10 our $VERSION = '1.32'; # VERSION
10 our $VERSION = '1.33'; # VERSION
1111
1212
1313 # problem with vanilla File::Temp is that is often uses
7979
8080 =head1 VERSION
8181
82 version 1.32
82 version 1.33
8383
8484 =head1 DESCRIPTION
8585
1616 require_ok 'FFI::Platypus::Closure';
1717 require_ok 'FFI::Platypus::Constant';
1818 require_ok 'FFI::Platypus::DL';
19 require_ok 'FFI::Platypus::Declare';
2019 require_ok 'FFI::Platypus::Function';
2120 require_ok 'FFI::Platypus::Internal';
2221 require_ok 'FFI::Platypus::Lang';
5655 ok -f 't/ffi_platypus_closure.t', 'test for FFI::Platypus::Closure';
5756 ok -f 't/ffi_platypus_constant.t', 'test for FFI::Platypus::Constant';
5857 ok -f 't/ffi_platypus_dl.t', 'test for FFI::Platypus::DL';
59 ok -f 't/ffi_platypus_declare.t', 'test for FFI::Platypus::Declare';
6058 ok -f 't/ffi_platypus_function.t', 'test for FFI::Platypus::Function';
6159 ok -f 't/ffi_platypus_internal.t', 'test for FFI::Platypus::Internal';
6260 ok -f 't/ffi_platypus_lang.t', 'test for FFI::Platypus::Lang';
+0
-242
t/ffi_platypus_declare.t less more
0 use strict;
1 use warnings;
2 use Test::More;
3 use FFI::CheckLib;
4 use FFI::Platypus::Declare;
5
6 my $libtest = find_lib lib => 'test', symbol => 'f0', libpath => 't/ffi';
7
8 subtest normal => sub {
9
10 { package Normal;
11
12 use FFI::Platypus::Declare;
13
14 lib $libtest;
15 attach 'f0', ['uint8'] => 'uint8';
16 attach [f0 => 'f1'], ['uint8'] => 'uint8';
17
18 attach [f0 => 'f0_wrap'] => ['uint8'] => 'uint8' => sub {
19 my($inner, $value) = @_;
20 $inner->($value+1)+2;
21 };
22
23 attach [f0 => 'f0_wrap2'] => ['uint8'] => 'uint8' => '$' => sub {
24 my($inner, $value) = @_;
25 $inner->($value+1)+2;
26 };
27 }
28
29 is Normal::f0(22), 22, 'f0(22) = 22';
30 is Normal::f1(22), 22, 'f1(22) = 22';
31 is Normal::f0_wrap(22), 25, 'f0_wrap(22) = 25';
32 is Normal::f0_wrap2(22), 25, 'f0_wrap2(22) = 25';
33 };
34
35 subtest prototype => sub {
36
37 my $value = eval q{
38 package ProtoType;
39
40 use FFI::Platypus::Declare;
41
42 BEGIN {
43 lib $libtest;
44 attach(f0 => ['uint8'] => 'uint8' => '$');
45 }
46
47 f0 22;
48 };
49
50 is $@, '', 'no compile error';
51 is $value, 22, 'f(22) = 22';
52
53 };
54
55 subtest 'with type aliases' => sub {
56
57 { package WithTypeAliases;
58
59 use FFI::Platypus::Declare
60 'string',
61 [int => 'myint'];
62
63 lib $libtest;
64 attach [my_atoi=>'atoi'], [string] => myint;
65 }
66
67 is WithTypeAliases::atoi("42"), 42, 'atoi("42") = 42';
68 };
69
70 subtest 'simple closure test' => sub {
71
72 { package ClosureSimple;
73
74 use FFI::Platypus::Declare;
75
76 our $closure = closure { $_[0]+1 };
77 }
78
79 isa_ok $ClosureSimple::closure, 'FFI::Platypus::Closure';
80 is $ClosureSimple::closure->(1), 2, 'closure.(1) = 2';
81 };
82
83 subtest 'abis' => sub {
84
85 my %abis = %{ FFI::Platypus->abis };
86
87 ok defined $abis{default_abi}, 'has a default ABI';
88
89 foreach my $abi (keys %abis)
90 {
91 subtest $abi => sub {
92 eval { abi $abi };
93 is $@, '', 'string';
94 eval { abi $abis{$abi} };
95 is $@, '', 'integer';
96 };
97 }
98
99 subtest 'bogus' => sub {
100 eval { abi 'bogus' };
101 like $@, qr{no such ABI: bogus}, 'string';
102 eval { abi 999999 };
103 like $@, qr{no such ABI: 999999}, 'integer';
104 };
105 };
106
107 subtest 'lang' => sub {
108
109 subtest C => sub {
110
111 package
112 Test1;
113
114 use Test::More;
115 use FFI::Platypus::Declare;
116
117 eval { type 'int' };
118 is $@, '', 'int is an okay type';
119 eval { type 'foo_t' };
120 isnt $@, '', 'foo_t is not an okay type';
121 note $@;
122 eval { type 'sint16' };
123 is $@, '', 'sint16 is an okay type';
124
125 };
126
127 subtest 'Foo constructor' => sub {
128
129 package
130 FFI::Platypus::Lang::Foo;
131
132 sub native_type_map
133 {
134 {
135 foo_t => 'sint16',
136 bar_t => 'uint32',
137 }
138 }
139
140 package
141 Test2;
142
143 use Test::More;
144 use FFI::Platypus::Declare;
145
146 lang 'Foo';
147
148 eval { type 'int' };
149 isnt $@, '', 'int is not an okay type';
150 note $@;
151 eval { type 'foo_t' };
152 is $@, '', 'foo_t is an okay type';
153 eval { type 'sint16' };
154 is $@, '', 'sint16 is an okay type';
155
156 is sizeof('foo_t'), 2, 'sizeof foo_t = 2';
157 is sizeof('bar_t'), 4, 'sizeof foo_t = 4';
158
159 };
160 };
161
162 subtest 'sizeof' => sub {
163 is sizeof 'uint32', 4, 'sizeof uint32 = 4';
164 is sizeof 'uint32[2]', 8, 'sizeof uint32[2] = 8';
165 };
166
167 subtest 'sticky' => sub {
168 package Foo;
169
170 use Test::More;
171 use FFI::Platypus::Declare
172 qw( uint8 void ),
173 ['(uint8)->uint8' => 'closure_t'];
174
175 lib $libtest;
176
177 attach [uint8_set_closure => 'set_closure'] => [closure_t] => void;
178 attach [uint8_call_closure => 'call_closure'] => [uint8] => uint8;
179
180 set_closure(sticky closure { $_[0] * 2 });
181 is call_closure(2), 4, 'call_closure(2) = 4';
182 };
183
184 subtest 'cast' => sub {
185 package Bar;
186
187 use Test::More;
188 use FFI::Platypus::Declare;
189
190 lib $libtest;
191
192 attach string_matches_foobarbaz => ['opaque'] => 'int';
193 attach string_return_foobarbaz => [] => 'opaque';
194 attach string_set_closure => ['opaque'] => 'void';
195 attach string_call_closure => ['string'] => 'void';
196
197 subtest 'cast from string to pointer' => sub {
198 my $string = "foobarbaz";
199 my $pointer = cast string => opaque => $string;
200
201 is string_matches_foobarbaz($pointer), 1, 'dynamic';
202
203 attach_cast cast1 => string => 'opaque';
204 my $pointer2 = cast1($string);
205
206 is string_matches_foobarbaz($pointer2), 1, 'static';
207
208 };
209
210 subtest 'cast from pointer to string' => sub {
211 my $pointer = string_return_foobarbaz();
212 my $string = cast opaque => string => $pointer;
213
214 is $string, "foobarbaz", "dynamic";
215
216 attach_cast cast2 => pointer => 'string';
217 my $string2 = cast2($pointer);
218
219 is $string2, "foobarbaz", "static";
220
221 };
222
223 subtest 'cast closure to opaque' => sub {
224 my $testname = 'dynamic';
225
226 my $closure = closure { is $_[0], "testvalue", $testname };
227 my $pointer = cast '(string)->void' => opaque => $closure;
228
229 string_set_closure($pointer);
230 string_call_closure("testvalue");
231
232 attach_cast 'cast3', '(string)->void' => 'opaque';
233 my $pointer2 = cast3($closure);
234
235 $testname = 'static';
236 string_set_closure($pointer2);
237 string_call_closure("testvalue");
238 };
239 };
240
241 done_testing;