FFI::Platypus#

📦 std

Call C functions in shared libraries from Perl, with no compiler.

FFI::Platypus->new(api => 2, lib => ...) finds a library; $ffi->attach(name => [argument types] => return type) makes a C function a Perl sub, $ffi->function(...) an object to call. Types cover the C integers and floats, long double and the complex types, strings, pointers and fixed arrays of them, records (C structs) by pointer and by value, closures (Perl subs C can call back), objects and custom types written in Perl.

This is a native implementation of FFI::Platypus 2.12’s compiled part, Platypus.xs with its xs/*.xs and helpers; its Perl modules are used unchanged. Its calls, types, records and closures are those of pperl’s own Peta::FFI, which can express everything FFI::Platypus can.

Synopsis#

use FFI::Platypus 2.00;

my $ffi = FFI::Platypus->new( api => 2, lib => undef );
$ffi->attach( puts   => ['string'] => 'int' );
$ffi->attach( strlen => ['string'] => 'size_t' );

puts("hello");
my $n = strlen("hello");                # 5

my $qsort = $ffi->function( qsort =>
    ['int*', 'size_t', 'size_t', '(opaque,opaque)->int'] => 'void' );

Differences from upstream#

  • Reading an array member of a record does not leak the array; perl leaks it and the reference on every read.

  • An index past an opaque[N] member warns “illegal index” and returns nothing, as for the other array members; perl reads beyond the member.

  • A reference to a hash or code for a pointer argument under api 2 warns and passes NULL; perl crashes.

  • An argument with get-magic - a regex capture, a tied scalar - passes its value; perl passes 0 for a number and NULL for a string, which crashes strlen($1).

  • A closure that a library calls from a thread of its own stops the program with a message saying so; perl runs Perl on that thread and crashes (“longjmp causes uninitialized stack frame”).

Modules#