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