1FFI::Platypus(3) User Contributed Perl Documentation FFI::Platypus(3)
2
3
4
6 FFI::Platypus - Write Perl bindings to non-Perl libraries with FFI. No
7 XS required.
8
10 version 2.05
11
13 use FFI::Platypus 2.00;
14
15 # for all new code you should use api => 2
16 my $ffi = FFI::Platypus->new(
17 api => 2,
18 lib => undef, # search libc
19 );
20
21 # call dynamically
22 $ffi->function( puts => ['string'] => 'int' )->call("hello world");
23
24 # attach as a xsub and call (much faster)
25 $ffi->attach( puts => ['string'] => 'int' );
26 puts("hello world");
27
29 Platypus is a library for creating interfaces to machine code libraries
30 written in languages like C, C++, Go, Fortran, Rust, Pascal.
31 Essentially anything that gets compiled into machine code. This
32 implementation uses libffi <https://sourceware.org/libffi/> to
33 accomplish this task. libffi <https://sourceware.org/libffi/> is
34 battle tested by a number of other scripting and virtual machine
35 languages, such as Python and Ruby to serve a similar role. There are
36 a number of reasons why you might want to write an extension with
37 Platypus instead of XS:
38
39 FFI / Platypus does not require messing with the guts of Perl
40 XS is less of an API and more of the guts of perl splayed out to do
41 whatever you want. That may at times be very powerful, but it can
42 also be a frustrating exercise in hair pulling.
43
44 FFI / Platypus is portable
45 Lots of languages have FFI interfaces, and it is subjectively
46 easier to port an extension written in FFI in Perl or another
47 language to FFI in another language or Perl. One goal of the
48 Platypus Project is to reduce common interface specifications to a
49 common format like JSON that could be shared between different
50 languages.
51
52 FFI / Platypus could be a bridge to Raku
53 One of those "other" languages could be Raku and Raku already has
54 an FFI interface I am told.
55
56 FFI / Platypus can be reimplemented
57 In a bright future with multiple implementations of Perl 5, each
58 interpreter will have its own implementation of Platypus, allowing
59 extensions to be written once and used on multiple platforms, in
60 much the same way that Ruby-FFI extensions can be use in Ruby,
61 JRuby and Rubinius.
62
63 FFI / Platypus is pure perl (sorta)
64 One Platypus script or module works on any platform where the
65 libraries it uses are available. That means you can deploy your
66 Platypus script in a shared filesystem where they may be run on
67 different platforms. It also means that Platypus modules do not
68 need to be installed in the platform specific Perl library path.
69
70 FFI / Platypus is not C or C++ centric
71 XS is implemented primarily as a bunch of C macros, which requires
72 at least some understanding of C, the C pre-processor, and some C++
73 caveats (since on some platforms Perl is compiled and linked with a
74 C++ compiler). Platypus on the other hand could be used to call
75 other compiled languages, like Fortran, Go, Rust, Pascal, C++, or
76 even assembly, allowing you to focus on your strengths.
77
78 FFI / Platypus does not require a parser
79 Inline isolates the extension developer from XS to some extent, but
80 it also requires a parser. The various Inline language bindings
81 are a great technical achievement, but I think writing a parser for
82 every language that you want to interface with is a bit of an anti-
83 pattern.
84
85 This document consists of an API reference, a set of examples, some
86 support and development (for contributors) information. If you are new
87 to Platypus or FFI, you may want to skip down to the EXAMPLES to get a
88 taste of what you can do with Platypus.
89
90 Platypus has extensive documentation of types at FFI::Platypus::Type
91 and its custom types API at FFI::Platypus::API.
92
93 You are strongly encouraged to use API level 1 for all new code. There
94 are a number of improvements and design fixes that you get for free.
95 You should even consider updating existing modules to use API level 1
96 where feasible. How do I do that you might ask? Simply pass in the
97 API level to the platypus constructor.
98
99 my $ffi = FFI::Platypus->new( api => 2 );
100
101 The Platypus documentation has already been updated to assume API level
102 1.
103
105 new
106 my $ffi = FFI::Platypus->new( api => 2, %options);
107
108 Create a new instance of FFI::Platypus.
109
110 Any types defined with this instance will be valid for this instance
111 only, so you do not need to worry about stepping on the toes of other
112 CPAN FFI / Platypus Authors.
113
114 Any functions found will be out of the list of libraries specified with
115 the lib attribute.
116
117 options
118
119 api [version 0.91]
120
121 Sets the API level. Legal values are
122
123 0 Original API level. See FFI::Platypus::TypeParser::Version0
124 for details on the differences.
125
126 1 Enable version 1 API type parser which allows pass-by-value
127 records and type decoration on basic types.
128
129 2 Enable version 2 API. All new code should be written with this
130 set to 1! The Platypus documentation assumes this api level is
131 set.
132
133 API version 2 is identical to version 1, except:
134
135 Pointer functions that return "NULL" will return "undef"
136 instead of empty list
137 This fixes a long standing design bug in Platypus.
138
139 Array references may be passed to pointer argument types
140 This replicates the behavior of array argument types with
141 no size. So the types "sint8*" and "sint8[]" behave
142 identically when an array reference is passed in. They
143 differ in that, as before, you can pass a scalar reference
144 into type "sint8*".
145
146 The fixed string type can be specified without pointer modifier
147 That is you can use "string(10)" instead of "string(10)*"
148 as you were previously able to in API 0.
149
150 lib Either a pathname (string) or a list of pathnames (array ref of
151 strings) to pre-populate the lib attribute. Use "[undef]" to
152 search the current process for symbols.
153
154 0.48
155
156 "undef" (without the array reference) can be used to search the
157 current process for symbols.
158
159 ignore_not_found
160 [version 0.15]
161
162 Set the ignore_not_found attribute.
163
164 lang
165 [version 0.18]
166
167 Set the lang attribute.
168
170 lib
171 $ffi->lib($path1, $path2, ...);
172 my @paths = $ffi->lib;
173
174 The list of libraries to search for symbols in.
175
176 The most portable and reliable way to find dynamic libraries is by
177 using FFI::CheckLib, like this:
178
179 use FFI::CheckLib 0.06;
180 $ffi->lib(find_lib_or_die lib => 'archive');
181 # finds libarchive.so on Linux
182 # libarchive.bundle on OS X
183 # libarchive.dll (or archive.dll) on Windows
184 # cygarchive-13.dll on Cygwin
185 # ...
186 # and will die if it isn't found
187
188 FFI::CheckLib has a number of options, such as checking for specific
189 symbols, etc. You should consult the documentation for that module.
190
191 As a special case, if you add "undef" as a "library" to be searched,
192 Platypus will also search the current process for symbols. This is
193 mostly useful for finding functions in the standard C library, without
194 having to know the name of the standard c library for your platform (as
195 it turns out it is different just about everywhere!).
196
197 You may also use the "find_lib" method as a shortcut:
198
199 $ffi->find_lib( lib => 'archive' );
200
201 ignore_not_found
202 [version 0.15]
203
204 $ffi->ignore_not_found(1);
205 my $ignore_not_found = $ffi->ignore_not_found;
206
207 Normally the attach and function methods will throw an exception if it
208 cannot find the name of the function you provide it. This will change
209 the behavior such that function will return "undef" when the function
210 is not found and attach will ignore functions that are not found. This
211 is useful when you are writing bindings to a library and have many
212 optional functions and you do not wish to wrap every call to function
213 or attach in an "eval".
214
215 lang
216 [version 0.18]
217
218 $ffi->lang($language);
219
220 Specifies the foreign language that you will be interfacing with. The
221 default is C. The foreign language specified with this attribute
222 changes the default native types (for example, if you specify Rust, you
223 will get "i32" as an alias for "sint32" instead of "int" as you do with
224 C).
225
226 If the foreign language plugin supports it, this will also enable
227 Platypus to find symbols using the demangled names (for example, if you
228 specify CPP for C++ you can use method names like "Foo::get_bar()" with
229 "attach" or "function".
230
231 api
232 [version 1.11]
233
234 my $level = $ffi->api;
235
236 Returns the API level of the Platypus instance.
237
239 type
240 $ffi->type($typename);
241 $ffi->type($typename => $alias);
242
243 Define a type. The first argument is the native or C name of the type.
244 The second argument (optional) is an alias name that you can use to
245 refer to this new type. See FFI::Platypus::Type for legal type
246 definitions.
247
248 Examples:
249
250 $ffi->type('sint32'); # only checks to see that sint32 is a valid type
251 $ffi->type('sint32' => 'myint'); # creates an alias myint for sint32
252 $ffi->type('bogus'); # dies with appropriate diagnostic
253
254 custom_type
255 $ffi->custom_type($alias => {
256 native_type => $native_type,
257 native_to_perl => $coderef,
258 perl_to_native => $coderef,
259 perl_to_native_post => $coderef,
260 });
261
262 Define a custom type. See FFI::Platypus::Type#Custom-Types for
263 details.
264
265 load_custom_type
266 $ffi->load_custom_type($name => $alias, @type_args);
267
268 Load the custom type defined in the module $name, and make an alias
269 $alias. If the custom type requires any arguments, they may be passed
270 in as @type_args. See FFI::Platypus::Type#Custom-Types for details.
271
272 If $name contains "::" then it will be assumed to be a fully qualified
273 package name. If not, then "FFI::Platypus::Type::" will be prepended to
274 it.
275
276 types
277 my @types = $ffi->types;
278 my @types = FFI::Platypus->types;
279
280 Returns the list of types that FFI knows about. This will include the
281 native "libffi" types (example: "sint32", "opaque" and "double") and
282 the normal C types (example: "unsigned int", "uint32_t"), any types
283 that you have defined using the type method, and custom types.
284
285 The list of types that Platypus knows about varies somewhat from
286 platform to platform, FFI::Platypus::Type includes a list of the core
287 types that you can always count on having access to.
288
289 It can also be called as a class method, in which case, no user defined
290 or custom types will be included in the list.
291
292 type_meta
293 my $meta = $ffi->type_meta($type_name);
294 my $meta = FFI::Platypus->type_meta($type_name);
295
296 Returns a hash reference with the meta information for the given type.
297
298 It can also be called as a class method, in which case, you won't be
299 able to get meta data on user defined types.
300
301 The format of the meta data is implementation dependent and subject to
302 change. It may be useful for display or debugging.
303
304 Examples:
305
306 my $meta = $ffi->type_meta('int'); # standard int type
307 my $meta = $ffi->type_meta('int[64]'); # array of 64 ints
308 $ffi->type('int[128]' => 'myintarray');
309 my $meta = $ffi->type_meta('myintarray'); # array of 128 ints
310
311 mangler
312 $ffi->mangler(\&mangler);
313
314 Specify a customer mangler to be used for symbol lookup. This is
315 usually useful when you are writing bindings for a library where all of
316 the functions have the same prefix. Example:
317
318 $ffi->mangler(sub {
319 my($symbol) = @_;
320 return "foo_$symbol";
321 });
322
323 $ffi->function( get_bar => [] => 'int' ); # attaches foo_get_bar
324
325 my $f = $ffi->function( set_baz => ['int'] => 'void' );
326 $f->call(22); # calls foo_set_baz
327
328 function
329 my $function = $ffi->function($name => \@argument_types => $return_type);
330 my $function = $ffi->function($address => \@argument_types => $return_type);
331 my $function = $ffi->function($name => \@argument_types => $return_type, \&wrapper);
332 my $function = $ffi->function($address => \@argument_types => $return_type, \&wrapper);
333
334 Returns an object that is similar to a code reference in that it can be
335 called like one.
336
337 Caveat: many situations require a real code reference, so at the price
338 of a performance penalty you can get one like this:
339
340 my $function = $ffi->function(...);
341 my $coderef = sub { $function->(@_) };
342
343 It may be better, and faster to create a real Perl function using the
344 attach method.
345
346 In addition to looking up a function by name you can provide the
347 address of the symbol yourself:
348
349 my $address = $ffi->find_symbol('my_function');
350 my $function = $ffi->function($address => ...);
351
352 Under the covers, function uses find_symbol when you provide it with a
353 name, but it is useful to keep this in mind as there are alternative
354 ways of obtaining a functions address. Example: a C function could
355 return the address of another C function that you might want to call.
356
357 [version 0.76]
358
359 If the last argument is a code reference, then it will be used as a
360 wrapper around the function when called. The first argument to the
361 wrapper will be the inner function, or if it is later attached an xsub.
362 This can be used if you need to verify/modify input/output data.
363
364 Examples:
365
366 my $function = $ffi->function('my_function_name', ['int', 'string'] => 'string');
367 my $return_string = $function->(1, "hi there");
368
369 [version 0.91]
370
371 my $function = $ffi->function( $name => \@fixed_argument_types => \@var_argument_types => $return_type);
372 my $function = $ffi->function( $name => \@fixed_argument_types => \@var_argument_types => $return_type, \&wrapper);
373 my $function = $ffi->function( $name => \@fixed_argument_types => \@var_argument_types);
374 my $function = $ffi->function( $name => \@fixed_argument_types => \@var_argument_types => \&wrapper);
375
376 Version 0.91 and later allows you to creat functions for c variadic
377 functions (such as printf, scanf, etc) which can take a variable number
378 of arguments. The first set of arguments are the fixed set, the second
379 set are the variable arguments to bind with. The variable argument
380 types must be specified in order to create a function object, so if you
381 need to call variadic function with different set of arguments then you
382 will need to create a new function object each time:
383
384 # int printf(const char *fmt, ...);
385 $ffi->function( printf => ['string'] => ['int'] => 'int' )
386 ->call("print integer %d\n", 42);
387 $ffi->function( printf => ['string'] => ['string'] => 'int' )
388 ->call("print string %s\n", 'platypus');
389
390 Some older versions of libffi and possibly some platforms may not
391 support variadic functions. If you try to create a one, then an
392 exception will be thrown.
393
394 [version 1.26]
395
396 If the return type is omitted then "void" will be the assumed return
397 type.
398
399 attach
400 $ffi->attach($name => \@argument_types => $return_type);
401 $ffi->attach([$c_name => $perl_name] => \@argument_types => $return_type);
402 $ffi->attach([$address => $perl_name] => \@argument_types => $return_type);
403 $ffi->attach($name => \@argument_types => $return_type, \&wrapper);
404 $ffi->attach([$c_name => $perl_name] => \@argument_types => $return_type, \&wrapper);
405 $ffi->attach([$address => $perl_name] => \@argument_types => $return_type, \&wrapper);
406
407 Find and attach a C function as a real live Perl xsub. The advantage
408 of attaching a function over using the function method is that it is
409 much much much faster since no object resolution needs to be done. The
410 disadvantage is that it locks the function and the FFI::Platypus
411 instance into memory permanently, since there is no way to deallocate
412 an xsub.
413
414 If just one $name is given, then the function will be attached in Perl
415 with the same name as it has in C. The second form allows you to give
416 the Perl function a different name. You can also provide an address
417 (the third form), just like with the function method.
418
419 Examples:
420
421 $ffi->attach('my_function_name', ['int', 'string'] => 'string');
422 $ffi->attach(['my_c_function_name' => 'my_perl_function_name'], ['int', 'string'] => 'string');
423 my $string1 = my_function_name($int);
424 my $string2 = my_perl_function_name($int);
425
426 [version 0.20]
427
428 If the last argument is a code reference, then it will be used as a
429 wrapper around the attached xsub. The first argument to the wrapper
430 will be the inner xsub. This can be used if you need to verify/modify
431 input/output data.
432
433 Examples:
434
435 $ffi->attach('my_function', ['int', 'string'] => 'string', sub {
436 my($my_function_xsub, $integer, $string) = @_;
437 $integer++;
438 $string .= " and another thing";
439 my $return_string = $my_function_xsub->($integer, $string);
440 $return_string =~ s/Belgium//; # HHGG remove profanity
441 $return_string;
442 });
443
444 [version 0.91]
445
446 $ffi->attach($name => \@fixed_argument_types => \@var_argument_types, $return_type);
447 $ffi->attach($name => \@fixed_argument_types => \@var_argument_types, $return_type, \&wrapper);
448
449 As of version 0.91 you can attach a variadic functions, if it is
450 supported by the platform / libffi that you are using. For details see
451 the "function" documentation. If not supported by the implementation
452 then an exception will be thrown.
453
454 closure
455 my $closure = $ffi->closure($coderef);
456 my $closure = FFI::Platypus->closure($coderef);
457
458 Prepares a code reference so that it can be used as a FFI closure (a
459 Perl subroutine that can be called from C code). For details on
460 closures, see FFI::Platypus::Type#Closures and FFI::Platypus::Closure.
461
462 cast
463 my $converted_value = $ffi->cast($original_type, $converted_type, $original_value);
464
465 The "cast" function converts an existing $original_value of type
466 $original_type into one of type $converted_type. Not all types are
467 supported, so care must be taken. For example, to get the address of a
468 string, you can do this:
469
470 my $address = $ffi->cast('string' => 'opaque', $string_value);
471
472 Something that won't work is trying to cast an array to anything:
473
474 my $address = $ffi->cast('int[10]' => 'opaque', \@list); # WRONG
475
476 attach_cast
477 $ffi->attach_cast("cast_name", $original_type, $converted_type);
478 $ffi->attach_cast("cast_name", $original_type, $converted_type, \&wrapper);
479 my $converted_value = cast_name($original_value);
480
481 This function attaches a cast as a permanent xsub. This will make it
482 faster and may be useful if you are calling a particular cast a lot.
483
484 [version 1.26]
485
486 A wrapper may be added as the last argument to "attach_cast" and works
487 just like the wrapper for "attach" and "function" methods.
488
489 sizeof
490 my $size = $ffi->sizeof($type);
491 my $size = FFI::Platypus->sizeof($type);
492
493 Returns the total size of the given type in bytes. For example to get
494 the size of an integer:
495
496 my $intsize = $ffi->sizeof('int'); # usually 4
497 my $longsize = $ffi->sizeof('long'); # usually 4 or 8 depending on platform
498
499 You can also get the size of arrays
500
501 my $intarraysize = $ffi->sizeof('int[64]'); # usually 4*64
502 my $intarraysize = $ffi->sizeof('long[64]'); # usually 4*64 or 8*64
503 # depending on platform
504
505 Keep in mind that "pointer" types will always be the pointer / word
506 size for the platform that you are using. This includes strings,
507 opaque and pointers to other types.
508
509 This function is not very fast, so you might want to save this value as
510 a constant, particularly if you need the size in a loop with many
511 iterations.
512
513 alignof
514 [version 0.21]
515
516 my $align = $ffi->alignof($type);
517
518 Returns the alignment of the given type in bytes.
519
520 kindof
521 [version 1.24]
522
523 my $kind = $ffi->kindof($type);
524
525 Returns the kind of a type. This is a string with a value of one of
526
527 "void"
528 "scalar"
529 "string"
530 "closure"
531 "record"
532 "record-value"
533 "pointer"
534 "array"
535 "object"
536
537 countof
538 [version 1.24]
539
540 my $count = $ffi->countof($type);
541
542 For array types returns the number of elements in the array (returns 0
543 for variable length array). For the "void" type returns 0. Returns 1
544 for all other types.
545
546 def
547 [version 1.24]
548
549 $ffi->def($package, $type, $value);
550 my $value = $ff->def($package, $type);
551
552 This method allows you to store data for types. If the $package is not
553 provided, then the caller's package will be used. $type must be a
554 legal Platypus type for the FFI::Platypus instance.
555
556 unitof
557 [version 1.24]
558
559 my $unittype = $ffi->unitof($type);
560
561 For array and pointer types, returns the basic type without the array
562 or pointer part. In other words, for "sin16[]" or "sint16*" it will
563 return "sint16".
564
565 find_lib
566 [version 0.20]
567
568 $ffi->find_lib( lib => $libname );
569
570 This is just a shortcut for calling FFI::CheckLib#find_lib and updating
571 the "lib" attribute appropriately. Care should be taken though, as
572 this method simply passes its arguments to FFI::CheckLib#find_lib, so
573 if your module or script is depending on a specific feature in
574 FFI::CheckLib then make sure that you update your prerequisites
575 appropriately.
576
577 find_symbol
578 my $address = $ffi->find_symbol($name);
579
580 Return the address of the given symbol (usually function).
581
582 bundle
583 [version 0.96 api = 1+]
584
585 $ffi->bundle($package, \@args);
586 $ffi->bundle(\@args);
587 $ffi->bundle($package);
588 $ffi->bundle;
589
590 This is an interface for bundling compiled code with your distribution
591 intended to eventually replace the "package" method documented above.
592 See FFI::Platypus::Bundle for details on how this works.
593
594 package
595 [version 0.15 api = 0]
596
597 $ffi->package($package, $file); # usually __PACKAGE__ and __FILE__ can be used
598 $ffi->package; # autodetect
599
600 Note: This method is officially discouraged in favor of "bundle"
601 described above.
602
603 If you use FFI::Build (or the older deprecated Module::Build::FFI to
604 bundle C code with your distribution, you can use this method to tell
605 the FFI::Platypus instance to look for symbols that came with the
606 dynamic library that was built when your distribution was installed.
607
608 abis
609 my $href = $ffi->abis;
610 my $href = FFI::Platypus->abis;
611
612 Get the legal ABIs supported by your platform and underlying
613 implementation. What is supported can vary a lot by CPU and by
614 platform, or even between 32 and 64 bit on the same CPU and platform.
615 They keys are the "ABI" names, also known as "calling conventions".
616 The values are integers used internally by the implementation to
617 represent those ABIs.
618
619 abi
620 $ffi->abi($name);
621
622 Set the ABI or calling convention for use in subsequent calls to
623 "function" or "attach". May be either a string name or integer value
624 from the "abis" method above.
625
627 Here are some examples. These examples are provided in full with the
628 Platypus distribution in the "examples" directory. There are also some
629 more examples in FFI::Platypus::Type that are related to types.
630
631 Passing and Returning Integers
632 C Source
633
634 int add(int a, int b) {
635 return a+b;
636 }
637
638 Perl Source
639
640 use FFI::Platypus 2.00;
641 use FFI::CheckLib qw( find_lib_or_die );
642 use File::Basename qw( dirname );
643
644 my $ffi = FFI::Platypus->new( api => 2, lib => './add.so' );
645 $ffi->attach( add => ['int', 'int'] => 'int' );
646
647 print add(1,2), "\n"; # prints 3
648
649 Execute
650
651 $ cc -shared -o add.so add.c
652 $ perl add.pl
653 3
654
655 Discussion
656
657 Basic types like integers and floating points are the easiest to pass
658 across the FFI boundary. Because they are values that are passed on
659 the stack (or through registers) you don't need to worry about memory
660 allocations or ownership.
661
662 Here we are building our own C dynamic library using the native C
663 compiler on a Unix like platform. The exact incantation that you will
664 use to do this would unfortunately depend on your platform and C
665 compiler.
666
667 By default, Platypus uses the Platypus C language plugin, which gives
668 you easy access to many of the basic types used by C APIs. (for
669 example "int", "unsigned long", "double", "size_t" and others).
670
671 If you are working with another language like Fortran, Go, Rust or Zig,
672 you will find similar examples where you can use the Platypus language
673 plugin for that language and use the native types.
674
675 String Arguments (with puts)
676 C API
677
678 cppreference - puts <https://en.cppreference.com/w/c/io/puts>
679
680 Perl Source
681
682 use FFI::Platypus 2.00;
683
684 my $ffi = FFI::Platypus->new( api => 2, lib => undef );
685 $ffi->attach( puts => ['string'] => 'int' );
686
687 puts("hello world");
688
689 Execute
690
691 $ perl puts.pl
692 hello world
693
694 Discussion
695
696 Passing strings into a C function as an argument is also pretty easy
697 using Platypus. Just use the "string" type, which is equivalent to the
698 C <char *> or "const char *" types.
699
700 In this example we are using the C Standard Library's "puts" function,
701 so we don't need to build our own C code. We do still need to tell
702 Platypus where to look for the "puts" symbol though, which is why we
703 set "lib" to "undef". This is a special value which tells Platypus to
704 search the Perl runtime executable itself (including any dynamic
705 libraries) for symbols. That helpfully includes the C Standard
706 Library.
707
708 Returning Strings
709 C Source
710
711 #include <string.h>
712 #include <stdlib.h>
713
714 const char *
715 string_reverse(const char *input)
716 {
717 static char *output = NULL;
718 int i, len;
719
720 if(output != NULL)
721 free(output);
722
723 if(input == NULL)
724 return NULL;
725
726 len = strlen(input);
727 output = malloc(len+1);
728
729 for(i=0; input[i]; i++)
730 output[len-i-1] = input[i];
731 output[len] = '\0';
732
733 return output;
734 }
735
736 Perl Source
737
738 use FFI::Platypus 2.00;
739
740 my $ffi = FFI::Platypus->new(
741 api => 2,
742 lib => './string_reverse.so',
743 );
744
745 $ffi->attach( string_reverse => ['string'] => 'string' );
746
747 print string_reverse("\nHello world");
748
749 string_reverse(undef);
750
751 Execute
752
753 $ cc -shared -o string_reverse.so string_reverse.c
754 $ perl string_reverse.pl
755 dlrow olleH
756
757 Discussion
758
759 The C code here takes an input ASCII string and reverses it, returning
760 the result. Note that it retains ownership of the string, the caller
761 is expected to use it before the next call to "reverse_string", or copy
762 it.
763
764 The Perl code simply declares the return value as "string" and is very
765 simple. This does bring up an inconsistency though, strings passed in
766 to a function as arguments are passed by reference, whereas the return
767 value is copied! This is usually what you want because C APIs usually
768 follow this pattern where you are expected to make your own copy of the
769 string.
770
771 At the end of the program we call "reverse_string" with "undef", which
772 gets translated to C as "NULL". This allows it to free the output
773 buffer so that the memory will not leak.
774
775 Returning and Freeing Strings with Embedded NULLs
776 C Source
777
778 #include <string.h>
779 #include <stdlib.h>
780
781 char *
782 string_crypt(const char *input, int len, const char *key)
783 {
784 char *output;
785 int i, n;
786
787 if(input == NULL)
788 return NULL;
789
790 output = malloc(len+1);
791 output[len] = '\0';
792
793 for(i=0, n=0; i<len; i++, n++) {
794 if(key[n] == '\0')
795 n = 0;
796 output[i] = input[i] ^ key[n];
797 }
798
799 return output;
800 }
801
802 void
803 string_crypt_free(char *output)
804 {
805 if(output != NULL)
806 free(output);
807 }
808
809 Perl Source
810
811 use FFI::Platypus 2.00;
812 use FFI::Platypus::Buffer qw( buffer_to_scalar );
813 use YAML ();
814
815 my $ffi = FFI::Platypus->new(
816 api => 2,
817 lib => './xor_cipher.so',
818 );
819
820 $ffi->attach( string_crypt_free => ['opaque'] );
821
822 $ffi->attach( string_crypt => ['string','int','string'] => 'opaque' => sub{
823 my($xsub, $input, $key) = @_;
824 my $ptr = $xsub->($input, length($input), $key);
825 my $output = buffer_to_scalar $ptr, length($input);
826 string_crypt_free($ptr);
827 return $output;
828 });
829
830 my $orig = "hello world";
831 my $key = "foobar";
832
833 print YAML::Dump($orig);
834 my $encrypted = string_crypt($orig, $key);
835 print YAML::Dump($encrypted);
836 my $decrypted = string_crypt($encrypted, $key);
837 print YAML::Dump($decrypted);
838
839 Execute
840
841 $ cc -shared -o xor_cipher.so xor_cipher.c
842 $ perl xor_cipher.pl
843 --- hello world
844 --- "\x0e\n\x03\x0e\x0eR\x11\0\x1d\x0e\x05"
845 --- hello world
846
847 Discussion
848
849 The C code here also returns a string, but it has some different
850 expectations, so we can't just use the "string" type like we did in the
851 previous example and copy the string.
852
853 This C code implements a simple XOR cipher. Given an input string and
854 a key it returns an encrypted or decrypted output string where the
855 characters are XORd with the key. There are some challenges here
856 though. First the input and output strings can have embedded "NULL"s
857 in them. For the string passed in, we can provide the length of the
858 input string. For the output, the "string" type expects a "NULL"
859 terminated string, so we can't use that. So instead we get a pointer
860 to the output using the "opaque" type. Because we know that the output
861 string is the same length as the input string we can convert the
862 pointer to a regular Perl string using the "buffer_to_scalar" function.
863 (For more details about working with buffers and strings see
864 FFI::Platypus::Buffer).
865
866 Next, the C code here does not keep the pointer to the output string,
867 as in the previous example. We are expected to call
868 "string_encrypt_free" when we are done. Since we are getting the
869 pointer back from the C code instead of copying the string that is easy
870 to do.
871
872 Finally, we are using a wrapper to hide a lot of this complexity from
873 our caller. The last argument to the "attach" call is a code reference
874 which will wrap around the C function, which is passed in as the first
875 argument of the wrapper. This is a good practice when writing modules,
876 to hide the complexity of C.
877
878 Pointers
879 C Source
880
881 void
882 swap(int *a, int *b)
883 {
884 int tmp = *b;
885 *b = *a;
886 *a = tmp;
887 }
888
889 Perl Source
890
891 use FFI::Platypus 2.00;
892
893 my $ffi = FFI::Platypus->new(
894 api => 2,
895 lib => './swap.so',
896 );
897
898 $ffi->attach( swap => ['int*','int*'] );
899
900 my $a = 1;
901 my $b = 2;
902
903 print "[a,b] = [$a,$b]\n";
904
905 swap( \$a, \$b );
906
907 print "[a,b] = [$a,$b]\n";
908
909 Execute
910
911 $ cc -shared -o swap.so swap.c
912 $ perl swap.pl
913 [a,b] = [1,2]
914 [a,b] = [2,1]
915
916 Discussion
917
918 Pointers are often use in C APIs to return simple values like this.
919 Platypus provides access to pointers to primitive types by appending
920 "*" to the primitive type. Here for example we are using "int*" to
921 create a function that takes two pointers to integers and swaps their
922 values.
923
924 When calling the function from Perl we pass in a reference to a scalar.
925 Strictly speaking Perl allows modifying the argument values to
926 subroutines, so we could have allowed just passing in a scalar, but in
927 the design of Platypus we decided that forcing the use of a reference
928 here emphasizes that you are passing a reference to the variable, not
929 just the value.
930
931 Not pictured in this example, but you can also pass in "undef" for a
932 pointer value and that will be translated into "NULL" on the C side.
933 You can also return a pointer to a primitive type from a function,
934 again this will be returned to Perl as a reference to a scalar.
935 Platypus also supports string pointers ("string*"). (Though the C
936 equivalent to a "string*" is a double pointer to char "char**").
937
938 Opaque Pointers (objects)
939 C Source
940
941 #include <string.h>
942 #include <stdlib.h>
943
944 typedef struct person_t {
945 char *name;
946 unsigned int age;
947 } person_t;
948
949 person_t *
950 person_new(const char *name, unsigned int age) {
951 person_t *self = malloc(sizeof(person_t));
952 self->name = strdup(name);
953 self->age = age;
954 }
955
956 const char *
957 person_name(person_t *self) {
958 return self->name;
959 }
960
961 unsigned int
962 person_age(person_t *self) {
963 return self->age;
964 }
965
966 void
967 person_free(person_t *self) {
968 free(self->name);
969 free(self);
970 }
971
972 Perl Source
973
974 use FFI::Platypus 2.00;
975
976 my $ffi = FFI::Platypus->new(
977 api => 2,
978 lib => './person.so',
979 );
980
981 $ffi->type( 'opaque' => 'person_t' );
982
983 $ffi->attach( person_new => ['string','unsigned int'] => 'person_t' );
984 $ffi->attach( person_name => ['person_t'] => 'string' );
985 $ffi->attach( person_age => ['person_t'] => 'unsigned int' );
986 $ffi->attach( person_free => ['person_t'] );
987
988 my $person = person_new( 'Roger Frooble Bits', 35 );
989
990 print "name = ", person_name($person), "\n";
991 print "age = ", person_age($person), "\n";
992
993 person_free($person);
994
995 Execute
996
997 $ cc -shared -o person.so person.c
998 $ perl person.pl
999 name = Roger Frooble Bits
1000 age = 35
1001
1002 Discussion
1003
1004 An opaque pointer is a pointer (memory address) that is pointing to
1005 something but you do not know the structure of that something. In C
1006 this is usually a "void*", but it could also be a pointer to a "struct"
1007 without a defined body.
1008
1009 This is often used to as an abstraction around objects in C. Here in
1010 the C code we have a "person_t" struct with functions to create (a
1011 constructor), free (a destructor) and query it (methods).
1012
1013 The Perl code can then use the constructor, methods and destructors
1014 without having to understand the internals. The "person_t" internals
1015 can also be changed without having to modify the calling code.
1016
1017 We use the Platypus type method to create an alias of "opaque" called
1018 "person_t". While this is not necessary, it does make the Perl code
1019 easier to understand.
1020
1021 In later examples we will see how to hide the use of "opaque" types
1022 further using the "object" type, but for some code direct use of
1023 "opaque" is appropriate.
1024
1025 Opaque Pointers (buffers and strings)
1026 C API
1027
1028 cppreference - free <https://en.cppreference.com/w/c/memory/free>
1029 cppreference - malloc <https://en.cppreference.com/w/c/memory/malloc>
1030 cppreference - memcpy
1031 <https://en.cppreference.com/w/c/string/byte/memcpy>
1032 cppreference - strdup
1033 <https://en.cppreference.com/w/c/string/byte/strdup>
1034
1035 Perl Source
1036
1037 use FFI::Platypus 2.00;
1038 use FFI::Platypus::Memory qw( malloc free memcpy strdup );
1039
1040 my $ffi = FFI::Platypus->new( api => 2 );
1041 my $buffer = malloc 14;
1042 my $ptr_string = strdup("hello there!!\n");
1043
1044 memcpy $buffer, $ptr_string, 15;
1045
1046 print $ffi->cast('opaque' => 'string', $buffer);
1047
1048 free $ptr_string;
1049 free $buffer;
1050
1051 Execute
1052
1053 $ perl malloc.pl
1054 hello there!!
1055
1056 Discussion
1057
1058 Another useful application of the "opaque" type is for dealing with
1059 buffers, and C strings that you do not immediately need to convert into
1060 Perl strings. This example is completely contrived, but we are using
1061 "malloc" to create a buffer of 14 bytes. We create a C string using
1062 "strdup", and then copy it into the buffer using "memcpy". When we are
1063 done with the "opaque" pointers we can free them using "free" since
1064 they. (This is generally only okay when freeing memory that was
1065 allocated by "malloc", which is the case for "strdup").
1066
1067 These memory tools, along with others are provided by the
1068 FFI::Platypus::Memory module, which is worth reviewing when you need to
1069 manipulate memory from Perl when writing your FFI code.
1070
1071 Just to verify that the "memcpy" did the right thing we convert the
1072 buffer into a Perl string and print it out using the Platypus cast
1073 method.
1074
1075 Arrays
1076 C Source
1077
1078 void
1079 array_reverse(int a[], int len) {
1080 int tmp, i;
1081
1082 for(i=0; i < len/2; i++) {
1083 tmp = a[i];
1084 a[i] = a[len-i-1];
1085 a[len-i-1] = tmp;
1086 }
1087 }
1088
1089 void
1090 array_reverse10(int a[10]) {
1091 array_reverse(a, 10);
1092 }
1093
1094 Perl Source
1095
1096 use FFI::Platypus 2.00;
1097
1098 my $ffi = FFI::Platypus->new(
1099 api => 2,
1100 lib => './array_reverse.so',
1101 );
1102
1103 $ffi->attach( array_reverse => ['int[]','int'] );
1104 $ffi->attach( array_reverse10 => ['int[10]'] );
1105
1106 my @a = (1..10);
1107 array_reverse10( \@a );
1108 print "$_ " for @a;
1109 print "\n";
1110
1111 @a = (1..20);
1112 array_reverse( \@a, 20 );
1113 print "$_ " for @a;
1114 print "\n";
1115
1116 Execute
1117
1118 $ cc -shared -o array_reverse.so array_reverse.c
1119 $ perl array_reverse.pl
1120 10 9 8 7 6 5 4 3 2 1
1121 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
1122
1123 Discussion
1124
1125 Arrays in C are passed as pointers, so the C code here reverses the
1126 array in place, rather than returning it. Arrays can also be fixed or
1127 variable length. If the array is variable length the length of the
1128 array must be provided in some way. In this case we explicitly pass in
1129 a length. Another way might be to end the array with 0, if you don't
1130 otherwise expect any 0 to appear in your data. For this reason,
1131 Platypus adds a zero (or "NULL" in the case of pointers) element at the
1132 end of the array when passing it into a variable length array type,
1133 although we do not use it here.
1134
1135 With Platypus you can declare an array type as being either fixed or
1136 variable length. Because Perl stores arrays in completely differently
1137 than C, a temporary array is created by Platypus, passed into the C
1138 function as a pointer. When the function returns the array is re-read
1139 by Platypus and the Perl array is updated with the new values. The
1140 temporary array is then freed.
1141
1142 You can use any primitive type for arrays, even "string". You can also
1143 return an array from a function. As in our discussion about strings,
1144 when you return an array the value is copied, which is usually what you
1145 want.
1146
1147 Pointers as Arrays
1148 C Source
1149
1150 #include <stdlib.h>
1151
1152 int
1153 array_sum(const int *a) {
1154 int i, sum;
1155 if(a == NULL)
1156 return -1;
1157 for(i=0, sum=0; a[i] != 0; i++)
1158 sum += a[i];
1159 return sum;
1160 }
1161
1162 Perl Source
1163
1164 use FFI::Platypus 2.00;
1165
1166 my $ffi = FFI::Platypus->new(
1167 api => 2,
1168 lib => './array_sum.so',
1169 );
1170
1171 $ffi->attach( array_sum => ['int*'] => 'int' );
1172
1173 print array_sum(undef), "\n"; # -1
1174 print array_sum([0]), "\n"; # 0
1175 print array_sum([1,2,3,0]), "\n"; # 6
1176
1177 Execute
1178
1179 $ cc -shared -o array_sum.so array_sum.c
1180 $ perl array_sum.pl
1181 -1
1182 0
1183 6
1184
1185 Discussion
1186
1187 Starting with the Platypus version 2 API, you can also pass an array
1188 reference in to a pointer argument.
1189
1190 In C pointer and array arguments are often used somewhat
1191 interchangeably. In this example we have an "array_sum" function that
1192 takes a zero terminated array of integers and computes the sum. If the
1193 pointer to the array is zero (0) then we return "-1" to indicate an
1194 error.
1195
1196 This is the main advantage from Perl for using pointer argument rather
1197 than an array one: the array argument will not let you pass in "undef"
1198 / "NULL".
1199
1200 Sending Strings to GUI on Unix with libnotify
1201 C API
1202
1203 Libnotify Reference Manual <https://developer-
1204 old.gnome.org/libnotify/unstable>
1205
1206 Perl Source
1207
1208 use FFI::CheckLib;
1209 use FFI::Platypus 2.00;
1210
1211 my $ffi = FFI::Platypus->new(
1212 api => 2,
1213 lib => find_lib_or_die(lib => 'notify'),
1214 );
1215
1216 $ffi->attach( notify_init => ['string'] );
1217 $ffi->attach( notify_uninit => [] );
1218 $ffi->attach( notify_notification_new => ['string', 'string', 'string'] => 'opaque' );
1219 $ffi->attach( notify_notification_show => ['opaque', 'opaque'] );
1220
1221 my $message = join "\n",
1222 "Hello from Platypus!",
1223 "Welcome to the fun",
1224 "world of FFI";
1225
1226 notify_init('Platypus Hello');
1227 my $n = notify_notification_new('Platypus Hello World', $message, 'dialog-information');
1228 notify_notification_show($n, undef);
1229 notify_uninit();
1230
1231 Execute
1232
1233 $ perl notify.pl
1234
1235 Discussion
1236
1237 The GNOME project provides an API to send notifications to its desktop
1238 environment. Nothing here is particularly new: all of the types and
1239 techniques are ones that we have seen before, except we are using a
1240 third party library, instead of using our own C code or the standard C
1241 library functions.
1242
1243 When using a third party library you have to know the name or location
1244 of it, which is not typically portable, so here we use FFI::CheckLib's
1245 find_lib_or_die function. If the library is not found the script will
1246 die with a useful diagnostic. FFI::CheckLib has a number of useful
1247 features and will integrate nicely with Alien::Build based Aliens.
1248
1249 The Win32 API with MessageBoxW
1250 Win32 API
1251
1252 MessageBoxW function (winuser.h) <https://learn.microsoft.com/en-
1253 us/windows/win32/api/winuser/nf-winuser-messageboxw>
1254
1255 Perl Source
1256
1257 use utf8;
1258 use FFI::Platypus 2.00;
1259
1260 my $ffi = FFI::Platypus->new(
1261 api => 2,
1262 lib => [undef],
1263 );
1264
1265 # see FFI::Platypus::Lang::Win32
1266 $ffi->lang('Win32');
1267
1268 # Send a Unicode string to the Windows API MessageBoxW function.
1269 use constant MB_OK => 0x00000000;
1270 use constant MB_DEFAULT_DESKTOP_ONLY => 0x00020000;
1271 $ffi->attach( [MessageBoxW => 'MessageBox'] => [ 'HWND', 'LPCWSTR', 'LPCWSTR', 'UINT'] => 'int' );
1272 MessageBox(undef, "I ❤️ Platypus", "Confession", MB_OK|MB_DEFAULT_DESKTOP_ONLY);
1273
1274 Execute
1275
1276 $ perl win32_messagebox.pl
1277
1278 Discussion
1279
1280 The API used by Microsoft Windows presents some unique challenges. On
1281 32 bit systems a different ABI is used than what is used by the
1282 standard C library. It also provides a rats nest of type aliases.
1283 Finally if you want to talk Unicode to any of the Windows API you will
1284 need to use "UTF-16LE" instead of "UTF-8" which is native to Perl.
1285 (The Win32 API refers to these as "LPWSTR" and "LPCWSTR" types). As
1286 much as possible the Win32 "language" plugin attempts to handle these
1287 challenges transparently. For more details see
1288 FFI::Platypus::Lang::Win32.
1289
1290 Discussion
1291
1292 The libnotify library is a desktop GUI notification system for the
1293 GNOME Desktop environment. This script sends a notification event that
1294 should show up as a balloon, for me it did so in the upper right hand
1295 corner of my screen.
1296
1297 Structured Data Records (by pointer or by reference)
1298 C API
1299
1300 cppreference - localtime
1301 <https://en.cppreference.com/w/c/chrono/localtime>
1302
1303 Perl Source
1304
1305 use FFI::Platypus 2.00;
1306 use FFI::C;
1307
1308 my $ffi = FFI::Platypus->new(
1309 api => 2,
1310 lib => [undef],
1311 );
1312 FFI::C->ffi($ffi);
1313
1314 package Unix::TimeStruct {
1315
1316 FFI::C->struct(tm => [
1317 tm_sec => 'int',
1318 tm_min => 'int',
1319 tm_hour => 'int',
1320 tm_mday => 'int',
1321 tm_mon => 'int',
1322 tm_year => 'int',
1323 tm_wday => 'int',
1324 tm_yday => 'int',
1325 tm_isdst => 'int',
1326 tm_gmtoff => 'long',
1327 _tm_zone => 'opaque',
1328 ]);
1329
1330 # For now 'string' is unsupported by FFI::C, but we
1331 # can cast the time zone from an opaque pointer to
1332 # string.
1333 sub tm_zone {
1334 my $self = shift;
1335 $ffi->cast('opaque', 'string', $self->_tm_zone);
1336 }
1337
1338 # attach the C localtime function
1339 $ffi->attach( localtime => ['time_t*'] => 'tm', sub {
1340 my($inner, $class, $time) = @_;
1341 $time = time unless defined $time;
1342 $inner->(\$time);
1343 });
1344 }
1345
1346 # now we can actually use our Unix::TimeStruct class
1347 my $time = Unix::TimeStruct->localtime;
1348 printf "time is %d:%d:%d %s\n",
1349 $time->tm_hour,
1350 $time->tm_min,
1351 $time->tm_sec,
1352 $time->tm_zone;
1353
1354 Execute
1355
1356 $ perl time_struct.pl
1357 time is 3:48:19 MDT
1358
1359 Discussion
1360
1361 C and other machine code languages frequently provide interfaces that
1362 include structured data records (defined using the "struct" keyword in
1363 C). Some libraries will provide an API which you are expected to read
1364 or write before and/or after passing them along to the library.
1365
1366 For C pointers to "strict", "union", nested "struct" and nested "union"
1367 structures, the easiest interface to use is via FFI::C. If you are
1368 working with a "struct" that must be passed by value (not pointers),
1369 then you will want to use FFI::Platypus::Record class instead. We will
1370 discuss an example of that next.
1371
1372 The C "localtime" function takes a pointer to a C struct. We simply
1373 define the members of the struct using the FFI::C "struct" method.
1374 Because we used the "ffi" method to tell FFI::C to use our local
1375 instance of FFI::Platypus it registers the "tm" type for us, and we can
1376 just start using it as a return type!
1377
1378 Structured Data Records (on stack or by value)
1379 C Source
1380
1381 #include <stdint.h>
1382 #include <string.h>
1383
1384 typedef struct color_t {
1385 char name[8];
1386 uint8_t red;
1387 uint8_t green;
1388 uint8_t blue;
1389 } color_t;
1390
1391 color_t
1392 color_increase_red(color_t color, uint8_t amount)
1393 {
1394 strcpy(color.name, "reddish");
1395 color.red += amount;
1396 return color;
1397 }
1398
1399 Perl Source
1400
1401 use FFI::Platypus 2.00;
1402
1403 my $ffi = FFI::Platypus->new(
1404 api => 2,
1405 lib => './color.so'
1406 );
1407
1408 package Color {
1409
1410 use FFI::Platypus::Record;
1411 use overload
1412 '""' => sub { shift->as_string },
1413 bool => sub { 1 }, fallback => 1;
1414
1415 record_layout_1($ffi,
1416 'string(8)' => 'name', qw(
1417 uint8 red
1418 uint8 green
1419 uint8 blue
1420 ));
1421
1422 sub as_string {
1423 my($self) = @_;
1424 sprintf "%s: [red:%02x green:%02x blue:%02x]",
1425 $self->name, $self->red, $self->green, $self->blue;
1426 }
1427
1428 }
1429
1430 $ffi->type('record(Color)' => 'color_t');
1431 $ffi->attach( color_increase_red => ['color_t','uint8'] => 'color_t' );
1432
1433 my $gray = Color->new(
1434 name => 'gray',
1435 red => 0xDC,
1436 green => 0xDC,
1437 blue => 0xDC,
1438 );
1439
1440 my $slightly_red = color_increase_red($gray, 20);
1441
1442 print "$gray\n";
1443 print "$slightly_red\n";
1444
1445 Execute
1446
1447 $ cc -shared -o color.so color.c
1448 $ perl color.pl
1449 gray: [red:dc green:dc blue:dc]
1450 reddish: [red:f0 green:dc blue:dc]
1451
1452 Discussion
1453
1454 In the C source of this example, we pass a C "struct" by value by
1455 copying it onto the stack. On the Perl side we create a "Color" class
1456 using FFI::Platypus::Record, which allows us to pass the structure the
1457 way the C source wants us to.
1458
1459 Generally you should only reach for FFI::Platypus::Record if you need
1460 to pass small records on the stack like this. For more complicated
1461 (including nested) data you want to use FFI::C using pointers.
1462
1463 Avoiding Copy Using Memory Windows (with libzmq3)
1464 C API
1465
1466 ØMQ/3.2.6 API Reference <http://api.zeromq.org/3-2:_start>
1467
1468 Perl Source
1469
1470 use constant ZMQ_IO_THREADS => 1;
1471 use constant ZMQ_MAX_SOCKETS => 2;
1472 use constant ZMQ_REQ => 3;
1473 use constant ZMQ_REP => 4;
1474 use FFI::CheckLib qw( find_lib_or_die );
1475 use FFI::Platypus 2.00;
1476 use FFI::Platypus::Memory qw( malloc );
1477 use FFI::Platypus::Buffer qw( scalar_to_buffer window );
1478
1479 my $endpoint = "ipc://zmq-ffi-$$";
1480 my $ffi = FFI::Platypus->new(
1481 api => 2,
1482 lib => find_lib_or_die lib => 'zmq',
1483 );
1484
1485 $ffi->attach(zmq_version => ['int*', 'int*', 'int*'] => 'void');
1486
1487 my($major,$minor,$patch);
1488 zmq_version(\$major, \$minor, \$patch);
1489 print "libzmq version $major.$minor.$patch\n";
1490 die "this script only works with libzmq 3 or better" unless $major >= 3;
1491
1492 $ffi->type('opaque' => 'zmq_context');
1493 $ffi->type('opaque' => 'zmq_socket');
1494 $ffi->type('opaque' => 'zmq_msg_t');
1495 $ffi->attach(zmq_ctx_new => [] => 'zmq_context');
1496 $ffi->attach(zmq_ctx_set => ['zmq_context', 'int', 'int'] => 'int');
1497 $ffi->attach(zmq_socket => ['zmq_context', 'int'] => 'zmq_socket');
1498 $ffi->attach(zmq_connect => ['opaque', 'string'] => 'int');
1499 $ffi->attach(zmq_bind => ['zmq_socket', 'string'] => 'int');
1500 $ffi->attach(zmq_send => ['zmq_socket', 'opaque', 'size_t', 'int'] => 'int');
1501 $ffi->attach(zmq_msg_init => ['zmq_msg_t'] => 'int');
1502 $ffi->attach(zmq_msg_recv => ['zmq_msg_t', 'zmq_socket', 'int'] => 'int');
1503 $ffi->attach(zmq_msg_data => ['zmq_msg_t'] => 'opaque');
1504 $ffi->attach(zmq_errno => [] => 'int');
1505 $ffi->attach(zmq_strerror => ['int'] => 'string');
1506
1507 my $context = zmq_ctx_new();
1508 zmq_ctx_set($context, ZMQ_IO_THREADS, 1);
1509
1510 my $socket1 = zmq_socket($context, ZMQ_REQ);
1511 zmq_connect($socket1, $endpoint);
1512
1513 my $socket2 = zmq_socket($context, ZMQ_REP);
1514 zmq_bind($socket2, $endpoint);
1515
1516 { # send
1517 our $sent_message = "hello there";
1518 my($pointer, $size) = scalar_to_buffer $sent_message;
1519 my $r = zmq_send($socket1, $pointer, $size, 0);
1520 die zmq_strerror(zmq_errno()) if $r == -1;
1521 }
1522
1523 { # recv
1524 my $msg_ptr = malloc 100;
1525 zmq_msg_init($msg_ptr);
1526 my $size = zmq_msg_recv($msg_ptr, $socket2, 0);
1527 die zmq_strerror(zmq_errno()) if $size == -1;
1528 my $data_ptr = zmq_msg_data($msg_ptr);
1529 window(my $recv_message, $data_ptr, $size);
1530 print "recv_message = $recv_message\n";
1531 }
1532
1533 Execute
1534
1535 $ perl zmq3.pl
1536 libzmq version 4.3.4
1537 recv_message = hello there
1538
1539 Discussion
1540
1541 ØMQ is a high-performance asynchronous messaging library. There are a
1542 few things to note here.
1543
1544 Firstly, sometimes there may be multiple versions of a library in the
1545 wild and you may need to verify that the library on a system meets your
1546 needs (alternatively you could support multiple versions and configure
1547 your bindings dynamically). Here we use "zmq_version" to ask libzmq
1548 which version it is.
1549
1550 "zmq_version" returns the version number via three integer pointer
1551 arguments, so we use the pointer to integer type: "int *". In order to
1552 pass pointer types, we pass a reference. In this case it is a reference
1553 to an undefined value, because zmq_version will write into the pointers
1554 the output values, but you can also pass in references to integers,
1555 floating point values and opaque pointer types. When the function
1556 returns the $major variable (and the others) has been updated and we
1557 can use it to verify that it supports the API that we require.
1558
1559 Finally we attach the necessary functions, send and receive a message.
1560 When we receive we use the FFI::Platypus::Buffer function "window"
1561 instead of "buffer_to_scalar". They have a similar effect in that the
1562 provide a scalar from a region of memory, but "window" doesn't have to
1563 copy any data, so it is cheaper to call. The only downside is that a
1564 windowed scalar like this is read-only.
1565
1566 libarchive
1567 C Documentation
1568
1569 <https://www.libarchive.org/>
1570
1571 Perl Source
1572
1573 use FFI::Platypus 2.00;
1574 use FFI::CheckLib qw( find_lib_or_die );
1575
1576 # This example uses FreeBSD's libarchive to list the contents of any
1577 # archive format that it suppors. We've also filled out a part of
1578 # the ArchiveWrite class that could be used for writing archive formats
1579 # supported by libarchive
1580
1581 my $ffi = FFI::Platypus->new(
1582 api => 2,
1583 lib => find_lib_or_die(lib => 'archive'),
1584 );
1585 $ffi->type('object(Archive)' => 'archive_t');
1586 $ffi->type('object(ArchiveRead)' => 'archive_read_t');
1587 $ffi->type('object(ArchiveWrite)' => 'archive_write_t');
1588 $ffi->type('object(ArchiveEntry)' => 'archive_entry_t');
1589
1590 package Archive {
1591 # base class is "abstract" having no constructor or destructor
1592
1593 $ffi->mangler(sub {
1594 my($name) = @_;
1595 "archive_$name";
1596 });
1597 $ffi->attach( error_string => ['archive_t'] => 'string' );
1598 }
1599
1600 package ArchiveRead {
1601 our @ISA = qw( Archive );
1602
1603 $ffi->mangler(sub {
1604 my($name) = @_;
1605 "archive_read_$name";
1606 });
1607
1608 $ffi->attach( new => ['string'] => 'archive_read_t' );
1609 $ffi->attach( [ free => 'DESTROY' ] => ['archive_t'] );
1610 $ffi->attach( support_filter_all => ['archive_t'] => 'int' );
1611 $ffi->attach( support_format_all => ['archive_t'] => 'int' );
1612 $ffi->attach( open_filename => ['archive_t','string','size_t'] => 'int' );
1613 $ffi->attach( next_header2 => ['archive_t', 'archive_entry_t' ] => 'int' );
1614 $ffi->attach( data_skip => ['archive_t'] => 'int' );
1615 # ... define additional read methods
1616 }
1617
1618 package ArchiveWrite {
1619
1620 our @ISA = qw( Archive );
1621
1622 $ffi->mangler(sub {
1623 my($name) = @_;
1624 "archive_write_$name";
1625 });
1626
1627 $ffi->attach( new => ['string'] => 'archive_write_t' );
1628 $ffi->attach( [ free => 'DESTROY' ] => ['archive_write_t'] );
1629 # ... define additional write methods
1630 }
1631
1632 package ArchiveEntry {
1633
1634 $ffi->mangler(sub {
1635 my($name) = @_;
1636 "archive_entry_$name";
1637 });
1638
1639 $ffi->attach( new => ['string'] => 'archive_entry_t' );
1640 $ffi->attach( [ free => 'DESTROY' ] => ['archive_entry_t'] );
1641 $ffi->attach( pathname => ['archive_entry_t'] => 'string' );
1642 # ... define additional entry methods
1643 }
1644
1645 use constant ARCHIVE_OK => 0;
1646
1647 # this is a Perl version of the C code here:
1648 # https://github.com/libarchive/libarchive/wiki/Examples#List_contents_of_Archive_stored_in_File
1649
1650 my $archive_filename = shift @ARGV;
1651 unless(defined $archive_filename)
1652 {
1653 print "usage: $0 archive.tar\n";
1654 exit;
1655 }
1656
1657 my $archive = ArchiveRead->new;
1658 $archive->support_filter_all;
1659 $archive->support_format_all;
1660
1661 my $r = $archive->open_filename($archive_filename, 1024);
1662 die "error opening $archive_filename: ", $archive->error_string
1663 unless $r == ARCHIVE_OK;
1664
1665 my $entry = ArchiveEntry->new;
1666
1667 while($archive->next_header2($entry) == ARCHIVE_OK)
1668 {
1669 print $entry->pathname, "\n";
1670 $archive->data_skip;
1671 }
1672
1673 Execute
1674
1675 $ perl archive_object.pl archive.tar
1676 archive.pl
1677 archive_object.pl
1678
1679 Discussion
1680
1681 libarchive is the implementation of "tar" for FreeBSD provided as a
1682 library and available on a number of platforms.
1683
1684 One interesting thing about libarchive is that it provides a kind of
1685 object oriented interface via opaque pointers. This example creates an
1686 abstract class "Archive", and concrete classes "ArchiveWrite",
1687 "ArchiveRead" and "ArchiveEntry". The concrete classes can even be
1688 inherited from and extended just like any Perl classes because of the
1689 way the custom types are implemented. We use Platypus's "object" type
1690 for this implementation, which is a wrapper around an "opaque" (can
1691 also be an integer) type that is blessed into a particular class.
1692
1693 Another advanced feature of this example is that we define a mangler to
1694 modify the symbol resolution for each class. This means we can do this
1695 when we define a method for Archive:
1696
1697 $ffi->attach( support_filter_all => ['archive_t'] => 'int' );
1698
1699 Rather than this:
1700
1701 $ffi->attach(
1702 [ archive_read_support_filter_all => 'support_read_filter_all' ] =>
1703 ['archive_t'] => 'int' );
1704 );
1705
1706 As nice as "libarchive" is, note that we have to shoehorn then
1707 "archive_free" function name into the Perl convention of using
1708 "DESTROY" as the destructor. We can easily do that for just this one
1709 function with:
1710
1711 $ffi->attach( [ free => 'DESTROY' ] => ['archive_t'] );
1712
1713 The "libarchive" is a large library with hundreds of methods. For
1714 comprehensive FFI bindings for "libarchive" see Archive::Libarchive.
1715
1716 unix open
1717 C API
1718
1719 Input-output system calls in C <https://www.geeksforgeeks.org/input-
1720 output-system-calls-c-create-open-close-read-write/>
1721
1722 Perl Source
1723
1724 use FFI::Platypus 2.00;
1725
1726 {
1727 package FD;
1728
1729 use constant O_RDONLY => 0;
1730 use constant O_WRONLY => 1;
1731 use constant O_RDWR => 2;
1732
1733 use constant IN => bless \do { my $in=0 }, __PACKAGE__;
1734 use constant OUT => bless \do { my $out=1 }, __PACKAGE__;
1735 use constant ERR => bless \do { my $err=2 }, __PACKAGE__;
1736
1737 my $ffi = FFI::Platypus->new( api => 2, lib => [undef]);
1738
1739 $ffi->type('object(FD,int)' => 'fd');
1740
1741 $ffi->attach( [ 'open' => 'new' ] => [ 'string', 'int', 'mode_t' ] => 'fd' => sub {
1742 my($xsub, $class, $fn, @rest) = @_;
1743 my $fd = $xsub->($fn, @rest);
1744 die "error opening $fn $!" if $$fd == -1;
1745 $fd;
1746 });
1747
1748 $ffi->attach( write => ['fd', 'string', 'size_t' ] => 'ssize_t' );
1749 $ffi->attach( read => ['fd', 'string', 'size_t' ] => 'ssize_t' );
1750 $ffi->attach( close => ['fd'] => 'int' );
1751 }
1752
1753 my $fd = FD->new("file_handle.txt", FD::O_RDONLY);
1754
1755 my $buffer = "\0" x 10;
1756
1757 while(my $br = $fd->read($buffer, 10))
1758 {
1759 FD::OUT->write($buffer, $br);
1760 }
1761
1762 $fd->close;
1763
1764 Execute
1765
1766 $ perl file_handle.pl
1767 Hello World
1768
1769 Discussion
1770
1771 The Unix file system calls use an integer handle for each open file.
1772 We can use the same "object" type that we used for libarchive above,
1773 except we let platypus know that the underlying type is "int" instead
1774 of "opaque" (the latter being the default for the "object" type).
1775 Mainly just for demonstration since Perl has much better IO libraries,
1776 but now we have an OO interface to the Unix IO functions.
1777
1778 Varadic Functions (with libcurl)
1779 C API
1780
1781 curl_easy_init <https://curl.se/libcurl/c/curl_easy_init.html>
1782 curl_easy_setopt <https://curl.se/libcurl/c/curl_easy_setopt.html>
1783 curl_easy_perform <https://curl.se/libcurl/c/curl_easy_perform.html>
1784 curl_easy_cleanup <https://curl.se/libcurl/c/curl_easy_cleanup.html>
1785 CURLOPT_URL <https://curl.se/libcurl/c/CURLOPT_URL.html>
1786
1787 Perl Source
1788
1789 use FFI::Platypus 2.00;
1790 use FFI::CheckLib qw( find_lib_or_die );
1791 use constant CURLOPT_URL => 10002;
1792
1793 my $ffi = FFI::Platypus->new(
1794 api => 2,
1795 lib => find_lib_or_die(lib => 'curl'),
1796 );
1797
1798 my $curl_handle = $ffi->function( 'curl_easy_init' => [] => 'opaque' )
1799 ->call;
1800
1801 $ffi->function( 'curl_easy_setopt' => ['opaque', 'enum' ] => ['string'] )
1802 ->call($curl_handle, CURLOPT_URL, "https://pl.atypus.org" );
1803
1804 $ffi->function( 'curl_easy_perform' => ['opaque' ] => 'enum' )
1805 ->call($curl_handle);
1806
1807 $ffi->function( 'curl_easy_cleanup' => ['opaque' ] )
1808 ->call($curl_handle);
1809
1810 Execute
1811
1812 $ perl curl.pl
1813 <!doctype html>
1814 <html lang="en">
1815 <head>
1816 <meta charset="utf-8" />
1817 <title>pl.atypus.org - Home for the Perl Platypus Project</title>
1818 ...
1819
1820 Discussion
1821
1822 The libcurl <https://curl.se/> library makes extensive use of "varadic"
1823 functions.
1824
1825 The C programming language and ABI have the concept of "varadic"
1826 functions that can take a variable number and variable type of
1827 arguments. Assuming you have a "libffi" that supports it (and most
1828 modern systems should), then you can create bindings to a varadic
1829 function by providing two sets of array references, one for the fixed
1830 arguments (for reasons, C varadic functions must have at least one) and
1831 one for variable arguments. In this example we call "curl_easy_setopt"
1832 as a varadic function.
1833
1834 For functions that have a large or infinite number of possible
1835 signatures it may be impracticable or impossible to attach them all.
1836 You can instead do as we did in this example, create a function object
1837 using the function method and call it immediately. This is not as
1838 performant either when you create or call as using the attach method,
1839 but in some cases the performance penalty may be worth it or
1840 unavoidable.
1841
1842 Callbacks (with libcurl)
1843 C API
1844
1845 curl_easy_init <https://curl.se/libcurl/c/curl_easy_init.html>
1846 curl_easy_setopt <https://curl.se/libcurl/c/curl_easy_setopt.html>
1847 curl_easy_perform <https://curl.se/libcurl/c/curl_easy_perform.html>
1848 curl_easy_cleanup <https://curl.se/libcurl/c/curl_easy_cleanup.html>
1849 CURLOPT_URL <https://curl.se/libcurl/c/CURLOPT_URL.html>
1850 CURLOPT_WRITEFUNCTION
1851 <https://curl.se/libcurl/c/CURLOPT_WRITEFUNCTION.html>
1852
1853 Perl Source
1854
1855 use FFI::Platypus 2.00;
1856 use FFI::CheckLib qw( find_lib_or_die );
1857 use FFI::Platypus::Buffer qw( window );
1858 use constant CURLOPT_URL => 10002;
1859 use constant CURLOPT_WRITEFUNCTION => 20011;
1860
1861 my $ffi = FFI::Platypus->new(
1862 api => 2,
1863 lib => find_lib_or_die(lib => 'curl'),
1864 );
1865
1866 my $curl_handle = $ffi->function( 'curl_easy_init' => [] => 'opaque' )
1867 ->call;
1868
1869 $ffi->function( 'curl_easy_setopt' => [ 'opaque', 'enum' ] => ['string'] )
1870 ->call($curl_handle, CURLOPT_URL, "https://pl.atypus.org" );
1871
1872 my $html;
1873
1874 my $closure = $ffi->closure(sub {
1875 my($ptr, $len, $num, $user) = @_;
1876 window(my $buf, $ptr, $len*$num);
1877 $html .= $buf;
1878 return $len*$num;
1879 });
1880
1881 $ffi->function( 'curl_easy_setopt' => [ 'opaque', 'enum' ] => ['(opaque,size_t,size_t,opaque)->size_t'] => 'enum' )
1882 ->call($curl_handle, CURLOPT_WRITEFUNCTION, $closure);
1883
1884 $ffi->function( 'curl_easy_perform' => [ 'opaque' ] => 'enum' )
1885 ->call($curl_handle);
1886
1887 $ffi->function( 'curl_easy_cleanup' => [ 'opaque' ] )
1888 ->call($curl_handle);
1889
1890 if($html =~ /<title>(.*?)<\/title>/) {
1891 print "$1\n";
1892 }
1893
1894 Execute
1895
1896 $ perl curl_callback.pl
1897 pl.atypus.org - Home for the Perl Platypus Project
1898
1899 Discussion
1900
1901 This example is similar to the previous one, except instead of letting
1902 libcurl <https://curl.se> write the content body to "STDOUT", we give
1903 it a callback to send the data to instead. The closure method can be
1904 used to create a callback function pointer that can be called from C.
1905 The type for the callback is in the form
1906 "(arg_type,arg_type,etc)->return_type" where the argument types are in
1907 parentheticals with an arrow between the argument types and the return
1908 type.
1909
1910 Inside the closure or callback we use the window function from
1911 FFI::Platypus::Buffer again to avoid an extra copy. We still have to
1912 copy the buffer to append it to $hmtl but it is at least one less copy.
1913
1914 bundle your own code
1915 C Source
1916
1917 "ffi/foo.c":
1918
1919 #include <ffi_platypus_bundle.h>
1920 #include <string.h>
1921
1922 typedef struct {
1923 char *name;
1924 int value;
1925 } foo_t;
1926
1927 foo_t*
1928 foo__new(const char *class_name, const char *name, int value) {
1929 (void)class_name;
1930 foo_t *self = malloc( sizeof( foo_t ) );
1931 self->name = strdup(name);
1932 self->value = value;
1933 return self;
1934 }
1935
1936 const char *
1937 foo__name(foo_t *self) {
1938 return self->name;
1939 }
1940
1941 int
1942 foo__value(foo_t *self) {
1943 return self->value;
1944 }
1945
1946 void
1947 foo__DESTROY(foo_t *self) {
1948 free(self->name);
1949 free(self);
1950 }
1951
1952 Perl Source
1953
1954 "lib/Foo.pm":
1955
1956 package Foo;
1957
1958 use strict;
1959 use warnings;
1960 use FFI::Platypus 2.00;
1961
1962 my $ffi = FFI::Platypus->new( api => 2 );
1963
1964 $ffi->type('object(Foo)' => 'foo_t');
1965 $ffi->mangler(sub {
1966 my $name = shift;
1967 $name =~ s/^/foo__/;
1968 $name;
1969 });
1970
1971 $ffi->bundle;
1972
1973 $ffi->attach( new => [ 'string', 'string', 'int' ] => 'foo_t' );
1974 $ffi->attach( name => [ 'foo_t' ] => 'string' );
1975 $ffi->attach( value => [ 'foo_t' ] => 'int' );
1976 $ffi->attach( DESTROY => [ 'foo_t' ] => 'void' );
1977
1978 1;
1979
1980 "t/foo.t":
1981
1982 use Test2::V0;
1983 use Foo;
1984
1985 my $foo = Foo->new("platypus", 10);
1986 isa_ok $foo, 'Foo';
1987 is $foo->name, "platypus";
1988 is $foo->value, 10;
1989
1990 done_testing;
1991
1992 "Makefile.PL":
1993
1994 use ExtUtils::MakeMaker;
1995 use FFI::Build::MM;
1996 my $fbmm = FFI::Build::MM->new;
1997 WriteMakefile(
1998 $fbmm->mm_args(
1999 NAME => 'Foo',
2000 DISTNAME => 'Foo',
2001 VERSION => '1.00',
2002 # ...
2003 )
2004 );
2005
2006 sub MY::postamble
2007 {
2008 $fbmm->mm_postamble;
2009 }
2010
2011 Execute
2012
2013 With prove:
2014
2015 $ prove -lvm
2016 t/foo.t ..
2017 # Seeded srand with seed '20221105' from local date.
2018 ok 1 - Foo=SCALAR->isa('Foo')
2019 ok 2
2020 ok 3
2021 1..3
2022 ok
2023 All tests successful.
2024 Files=1, Tests=3, 0 wallclock secs ( 0.00 usr 0.00 sys + 0.10 cusr 0.00 csys = 0.10 CPU)
2025 Result: PASS
2026
2027 With ExtUtils::MakeMaker:
2028
2029 $ perl Makefile.PL
2030 Generating a Unix-style Makefile
2031 Writing Makefile for Foo
2032 Writing MYMETA.yml and MYMETA.json
2033 $ make
2034 cp lib/Foo.pm blib/lib/Foo.pm
2035 "/home/ollisg/opt/perl/5.37.5/bin/perl5.37.5" -MFFI::Build::MM=cmd -e fbx_build
2036 CC ffi/foo.c
2037 LD blib/lib/auto/share/dist/Foo/lib/libFoo.so
2038 $ make test
2039 "/home/ollisg/opt/perl/5.37.5/bin/perl5.37.5" -MFFI::Build::MM=cmd -e fbx_build
2040 "/home/ollisg/opt/perl/5.37.5/bin/perl5.37.5" -MFFI::Build::MM=cmd -e fbx_test
2041 PERL_DL_NONLAZY=1 "/home/ollisg/opt/perl/5.37.5/bin/perl5.37.5" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
2042 t/foo.t .. ok
2043 All tests successful.
2044 Files=1, Tests=3, 1 wallclock secs ( 0.00 usr 0.00 sys + 0.03 cusr 0.00 csys = 0.03 CPU)
2045 Result: PASS
2046
2047 Discussion
2048
2049 You can bundle your own C code with your Perl extension. There are a
2050 number of reasons you might want to do this Sometimes you need to
2051 optimize a tight loop for speed. Or you might need a little bit of
2052 glue code for your bindings to a library that isn't inherently FFI
2053 friendly. Either way what you want is the FFI::Build system on the
2054 install step and the FFI::Platypus::Bundle interface on the runtime
2055 step. If you are using Dist::Zilla for your distribution, you will
2056 also want to check out the Dist::Zilla::Plugin::FFI::Build plugin to
2057 make this as painless as possible.
2058
2059 One of the nice things about the bundle interface is that it is smart
2060 enough to work with either App::Prove or ExtUtils::MakeMaker. This
2061 means, unlike XS, you do not need to explicitly compile your C code in
2062 development mode, that will be done for you when you call
2063 "$ffi->bundle"
2064
2066 How do I get constants defined as macros in C header files
2067 This turns out to be a challenge for any language calling into C, which
2068 frequently uses "#define" macros to define constants like so:
2069
2070 #define FOO_STATIC 1
2071 #define FOO_DYNAMIC 2
2072 #define FOO_OTHER 3
2073
2074 As macros are expanded and their definitions are thrown away by the C
2075 pre-processor there isn't any way to get the name/value mappings from
2076 the compiled dynamic library.
2077
2078 You can manually create equivalent constants in your Perl source:
2079
2080 use constant FOO_STATIC => 1;
2081 use constant FOO_DYNAMIC => 2;
2082 use constant FOO_OTHER => 3;
2083
2084 If there are a lot of these types of constants you might want to
2085 consider using a tool (Convert::Binary::C can do this) that can extract
2086 the constants for you.
2087
2088 See also the "Integer constants" example in FFI::Platypus::Type.
2089
2090 You can also use the new Platypus bundle interface to define Perl
2091 constants from C space. This is more reliable, but does require a
2092 compiler at install time. It is recommended mainly for writing
2093 bindings against libraries that have constants that can vary widely
2094 from platform to platform. See FFI::Platypus::Constant for details.
2095
2096 What about enums?
2097 The C enum types are integers. The underlying type is up to the
2098 platform, so Platypus provides "enum" and "senum" types for unsigned
2099 and singed enums respectively. At least some compilers treat signed
2100 and unsigned enums as different types. The enum values are essentially
2101 the same as macro constants described above from an FFI perspective.
2102 Thus the process of defining enum values is identical to the process of
2103 defining macro constants in Perl.
2104
2105 For more details on enumerated types see "Enum types" in
2106 FFI::Platypus::Type.
2107
2108 There is also a type plugin (FFI::Platypus::Type::Enum) that can be
2109 helpful in writing interfaces that use enums.
2110
2111 Memory leaks
2112 There are a couple places where memory is allocated, but never
2113 deallocated that may look like memory leaks by tools designed to find
2114 memory leaks like valgrind. This memory is intended to be used for the
2115 lifetime of the perl process so there normally this isn't a problem
2116 unless you are embedding a Perl interpreter which doesn't closely match
2117 the lifetime of your overall application.
2118
2119 Specifically:
2120
2121 type cache
2122 some types are cached and not freed. These are needed as long as
2123 there are FFI functions that could be called.
2124
2125 attached functions
2126 Attaching a function as an xsub will definitely allocate memory
2127 that won't be freed because the xsub could be called at any time,
2128 including in "END" blocks.
2129
2130 The Platypus team plans on adding a hook to free some of this "leaked"
2131 memory for use cases where Perl and Platypus are embedded in a larger
2132 application where the lifetime of the Perl process is significantly
2133 smaller than the overall lifetime of the whole process.
2134
2135 I get seg faults on some platforms but not others with a library using
2136 pthreads.
2137 On some platforms, Perl isn't linked with "libpthreads" if Perl threads
2138 are not enabled. On some platforms this doesn't seem to matter,
2139 "libpthreads" can be loaded at runtime without much ill-effect. (Linux
2140 from my experience doesn't seem to mind one way or the other). Some
2141 platforms are not happy about this, and about the only thing that you
2142 can do about it is to build Perl such that it links with "libpthreads"
2143 even if it isn't a threaded Perl.
2144
2145 This is not really an FFI issue, but a Perl issue, as you will have the
2146 same problem writing XS code for the such libraries.
2147
2148 Doesn't work on Perl 5.10.0.
2149 The first point release of Perl 5.10 was buggy, and is not supported by
2150 Platypus. Please upgrade to a newer Perl.
2151
2153 Platypus and Native Interfaces like libffi rely on the availability of
2154 dynamic libraries. Things not supported include:
2155
2156 Systems that lack dynamic library support
2157 Like MS-DOS
2158
2159 Systems that are not supported by libffi
2160 Like OpenVMS
2161
2162 Languages that do not support using dynamic libraries from other
2163 languages
2164 This used to be the case with Google's Go, but is no longer the
2165 case. This is a problem for C / XS code as well.
2166
2167 Languages that do not compile to machine code
2168 Like .NET based languages and Java.
2169
2170 The documentation has a bias toward using FFI / Platypus with C. This
2171 is my fault, as my background in mainly in C/C++ programmer (when I am
2172 not writing Perl). In many places I use "C" as a short form for "any
2173 language that can generate machine code and is callable from C". I
2174 welcome pull requests to the Platypus core to address this issue. In
2175 an attempt to ease usage of Platypus by non C programmers, I have
2176 written a number of foreign language plugins for various popular
2177 languages (see the SEE ALSO below). These plugins come with examples
2178 specific to those languages, and documentation on common issues related
2179 to using those languages with FFI. In most cases these are available
2180 for easy adoption for those with the know-how or the willingness to
2181 learn. If your language doesn't have a plugin YET, that is just
2182 because you haven't written it yet.
2183
2185 IRC: #native on irc.perl.org
2186
2187 (click for instant chat room login)
2188 <http://chat.mibbit.com/#native@irc.perl.org>
2189
2190 If something does not work the way you think it should, or if you have
2191 a feature request, please open an issue on this project's GitHub Issue
2192 tracker:
2193
2194 <https://github.com/perlFFI/FFI-Platypus/issues>
2195
2197 If you have implemented a new feature or fixed a bug then you may make
2198 a pull request on this project's GitHub repository:
2199
2200 <https://github.com/PerlFFI/FFI-Platypus/pulls>
2201
2202 This project is developed using Dist::Zilla. The project's git
2203 repository also comes with the "Makefile.PL" file necessary for
2204 building, testing (and even installing if necessary) without
2205 Dist::Zilla. Please keep in mind though that these files are generated
2206 so if changes need to be made to those files they should be done
2207 through the project's "dist.ini" file. If you do use Dist::Zilla and
2208 already have the necessary plugins installed, then I encourage you to
2209 run "dzil test" before making any pull requests. This is not a
2210 requirement, however, I am happy to integrate especially smaller
2211 patches that need tweaking to fit the project standards. I may push
2212 back and ask you to write a test case or alter the formatting of a
2213 patch depending on the amount of time I have and the amount of code
2214 that your patch touches.
2215
2216 This project's GitHub issue tracker listed above is not Write-Only. If
2217 you want to contribute then feel free to browse through the existing
2218 issues and see if there is something you feel you might be good at and
2219 take a whack at the problem. I frequently open issues myself that I
2220 hope will be accomplished by someone in the future but do not have time
2221 to immediately implement myself.
2222
2223 Another good area to help out in is documentation. I try to make sure
2224 that there is good document coverage, that is there should be
2225 documentation describing all the public features and warnings about
2226 common pitfalls, but an outsider's or alternate view point on such
2227 things would be welcome; if you see something confusing or lacks
2228 sufficient detail I encourage documentation only pull requests to
2229 improve things.
2230
2231 The Platypus distribution comes with a test library named "libtest"
2232 that is normally automatically built by "./Build test". If you prefer
2233 to use "prove" or run tests directly, you can use the "./Build libtest"
2234 command to build it. Example:
2235
2236 % perl Makefile.PL
2237 % make
2238 % make ffi-test
2239 % prove -bv t
2240 # or an individual test
2241 % perl -Mblib t/ffi_platypus_memory.t
2242
2243 The build process also respects these environment variables:
2244
2245 FFI_PLATYPUS_DEBUG_FAKE32
2246 When building Platypus on 32 bit Perls, it will use the Math::Int64
2247 C API and make Math::Int64 a prerequisite. Setting this
2248 environment variable will force Platypus to build with both of
2249 those options on a 64 bit Perl as well.
2250
2251 % env FFI_PLATYPUS_DEBUG_FAKE32=1 perl Makefile.PL
2252 DEBUG_FAKE32:
2253 + making Math::Int64 a prereq
2254 + Using Math::Int64's C API to manipulate 64 bit values
2255 Generating a Unix-style Makefile
2256 Writing Makefile for FFI::Platypus
2257 Writing MYMETA.yml and MYMETA.json
2258 %
2259
2260 FFI_PLATYPUS_NO_ALLOCA
2261 Platypus uses the non-standard and somewhat controversial C
2262 function "alloca" by default on platforms that support it. I
2263 believe that Platypus uses it responsibly to allocate small amounts
2264 of memory for argument type parameters, and does not use it to
2265 allocate large structures like arrays or buffers. If you prefer
2266 not to use "alloca" despite these precautions, then you can turn
2267 its use off by setting this environment variable when you run
2268 "Makefile.PL":
2269
2270 helix% env FFI_PLATYPUS_NO_ALLOCA=1 perl Makefile.PL
2271 NO_ALLOCA:
2272 + alloca() will not be used, even if your platform supports it.
2273 Generating a Unix-style Makefile
2274 Writing Makefile for FFI::Platypus
2275 Writing MYMETA.yml and MYMETA.json
2276
2277 V When building platypus may hide some of the excessive output when
2278 probing and building, unless you set "V" to a true value.
2279
2280 % env V=1 perl Makefile.PL
2281 % make V=1
2282 ...
2283
2284 Coding Guidelines
2285 • Do not hesitate to make code contribution. Making useful
2286 contributions is more important than following byzantine
2287 bureaucratic coding regulations. We can always tweak things later.
2288
2289 • Please make an effort to follow existing coding style when making
2290 pull requests.
2291
2292 • Platypus supports all production Perl releases since 5.8.1. For
2293 that reason, please do not introduce any code that requires a newer
2294 version of Perl.
2295
2296 Performance Testing
2297 As Mark Twain was fond of saying there are four types of lies: lies,
2298 damn lies, statistics and benchmarks. That being said, it can
2299 sometimes be helpful to compare the runtime performance of Platypus if
2300 you are making significant changes to the Platypus Core. For that I
2301 use `FFI-Performance`, which can be found in my GitHub repository here:
2302
2303 <https://github.com/Perl5-FFI/FFI-Performance>
2304
2305 System integrators
2306 This distribution uses Alien::FFI in fallback mode, meaning if the
2307 system doesn't provide "pkg-config" and "libffi" it will attempt to
2308 download "libffi" and build it from source. If you are including
2309 Platypus in a larger system (for example a Linux distribution) you only
2310 need to make sure to declare "pkg-config" or "pkgconf" and the
2311 development package for "libffi" as prereqs for this module.
2312
2314 Extending Platypus
2315 FFI::Platypus::Type
2316 Type definitions for Platypus.
2317
2318 FFI::C
2319 Interface for defining structured data records for use with
2320 Platypus. It supports C "struct", "union", nested structures and
2321 arrays of all of those. It only supports passing these types by
2322 reference or pointer, so if you need to pass structured data by
2323 value see FFI::Platypus::Record below.
2324
2325 FFI::Platypus::Record
2326 Interface for defining structured data records for use with
2327 Platypus. Included in the Platypus core. Supports pass by value
2328 which is uncommon in C, but frequently used in languages like Rust
2329 and Go. Consider using FFI::C instead if you don't need to pass by
2330 value.
2331
2332 FFI::Platypus::API
2333 The custom types API for Platypus.
2334
2335 FFI::Platypus::Memory
2336 Memory functions for FFI.
2337
2338 Languages
2339 FFI::Platypus::Lang::C
2340 Documentation and tools for using Platypus with the C programming
2341 language
2342
2343 FFI::Platypus::Lang::CPP
2344 Documentation and tools for using Platypus with the C++ programming
2345 language
2346
2347 FFI::Platypus::Lang::Fortran
2348 Documentation and tools for using Platypus with Fortran
2349
2350 FFI::Platypus::Lang::Go
2351 Documentation and tools for using Platypus with Go
2352
2353 FFI::Platypus::Lang::Pascal
2354 Documentation and tools for using Platypus with Free Pascal
2355
2356 FFI::Platypus::Lang::Rust
2357 Documentation and tools for using Platypus with the Rust
2358 programming language
2359
2360 FFI::Platypus::Lang::ASM
2361 Documentation and tools for using Platypus with the Assembly
2362
2363 FFI::Platypus::Lang::Win32
2364 Documentation and tools for using Platypus with the Win32 API.
2365
2366 FFI::Platypus::Lang::Zig
2367 Documentation and tools for using Platypus with the Zig programming
2368 language
2369
2370 Wasm and Wasm::Wasmtime
2371 Modules for writing WebAssembly bindings in Perl. This allows you
2372 to call functions written in any language supported by WebAssembly.
2373 These modules are also implemented using Platypus.
2374
2375 Other Tools Related Tools Useful for FFI
2376 FFI::CheckLib
2377 Find dynamic libraries in a portable way.
2378
2379 Convert::Binary::C
2380 A great interface for decoding C data structures, including
2381 "struct"s, "enum"s, "#define"s and more.
2382
2383 pack and unpack
2384 Native to Perl functions that can be used to decode C "struct"
2385 types.
2386
2387 C::Scan
2388 This module can extract constants and other useful objects from C
2389 header files that may be relevant to an FFI application. One
2390 downside is that its use may require development packages to be
2391 installed.
2392
2393 Other Foreign Function Interfaces
2394 Dyn A wrapper around dyncall <https://dyncall.org>, which is itself an
2395 alternative to libffi <https://sourceware.org/libffi/>.
2396
2397 NativeCall
2398 Promising interface to Platypus inspired by Raku.
2399
2400 Win32::API
2401 Microsoft Windows specific FFI style interface.
2402
2403 FFI Older, simpler, less featureful FFI. It used to be implemented
2404 using FSF's "ffcall". Because "ffcall" has been unsupported for
2405 some time, I reimplemented this module using FFI::Platypus.
2406
2407 C::DynaLib
2408 Another FFI for Perl that doesn't appear to have worked for a long
2409 time.
2410
2411 C::Blocks
2412 Embed a tiny C compiler into your Perl scripts.
2413
2414 P5NCI
2415 Yet another FFI like interface that does not appear to be supported
2416 or under development anymore.
2417
2418 Other
2419 Alien::FFI
2420 Provides libffi for Platypus during its configuration and build
2421 stages.
2422
2424 In addition to the contributors mentioned below, I would like to
2425 acknowledge Brock Wilcox (AWWAIID) and Meredith Howard (MHOWARD) whose
2426 work on "FFI::Sweet" not only helped me get started with FFI but
2427 significantly influenced the design of Platypus.
2428
2429 Dan Book, who goes by Grinnz on IRC for answering user questions about
2430 FFI and Platypus.
2431
2432 In addition I'd like to thank Alessandro Ghedini (ALEXBIO) whose work
2433 on another Perl FFI library helped drive some of the development ideas
2434 for FFI::Platypus.
2435
2437 Author: Graham Ollis <plicease@cpan.org>
2438
2439 Contributors:
2440
2441 Bakkiaraj Murugesan (bakkiaraj)
2442
2443 Dylan Cali (calid)
2444
2445 pipcet
2446
2447 Zaki Mughal (zmughal)
2448
2449 Fitz Elliott (felliott)
2450
2451 Vickenty Fesunov (vyf)
2452
2453 Gregor Herrmann (gregoa)
2454
2455 Shlomi Fish (shlomif)
2456
2457 Damyan Ivanov
2458
2459 Ilya Pavlov (Ilya33)
2460
2461 Petr Písař (ppisar)
2462
2463 Mohammad S Anwar (MANWAR)
2464
2465 Håkon Hægland (hakonhagland, HAKONH)
2466
2467 Meredith (merrilymeredith, MHOWARD)
2468
2469 Diab Jerius (DJERIUS)
2470
2471 Eric Brine (IKEGAMI)
2472
2473 szTheory
2474
2475 José Joaquín Atria (JJATRIA)
2476
2477 Pete Houston (openstrike, HOUSTON)
2478
2480 This software is copyright (c) 2015-2022 by Graham Ollis.
2481
2482 This is free software; you can redistribute it and/or modify it under
2483 the same terms as the Perl 5 programming language system itself.
2484
2485
2486
2487perl v5.36.0 2022-11-18 FFI::Platypus(3)