FFI-Platypus

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN


     $ cc -shared -o array_sum.so array_sum.c
     $ perl array_sum.pl
     -1
     0
     6

  Discussion

    Starting with the Platypus version 2 API, you can also pass an array
    reference in to a pointer argument.

    In C pointer and array arguments are often used somewhat
    interchangeably. In this example we have an array_sum function that
    takes a zero terminated array of integers and computes the sum. If the
    pointer to the array is zero (0) then we return -1 to indicate an
    error.

    This is the main advantage from Perl for using pointer argument rather
    than an array one: the array argument will not let you pass in undef /
    NULL.

 Sending Strings to GUI on Unix with libnotify

  C API

    Libnotify Reference Manual
    <https://developer-old.gnome.org/libnotify/unstable>

  Perl Source

     use FFI::CheckLib;
     use FFI::Platypus 2.00;
     
     my $ffi = FFI::Platypus->new(
       api => 2,
       lib => find_lib_or_die(lib => 'notify'),
     );
     
     $ffi->attach( notify_init              => ['string']                                  );
     $ffi->attach( notify_uninit            => []                                          );
     $ffi->attach( notify_notification_new  => ['string', 'string', 'string']  => 'opaque' );
     $ffi->attach( notify_notification_show => ['opaque', 'opaque']                        );
     
     my $message = join "\n",
       "Hello from Platypus!",
       "Welcome to the fun",
       "world of FFI";
     
     notify_init('Platypus Hello');
     my $n = notify_notification_new('Platypus Hello World', $message, 'dialog-information');
     notify_notification_show($n, undef);
     notify_uninit();

  Execute

     $ perl notify.pl

  Discussion

    The GNOME project provides an API to send notifications to its desktop
    environment. Nothing here is particularly new: all of the types and
    techniques are ones that we have seen before, except we are using a
    third party library, instead of using our own C code or the standard C
    library functions.

    When using a third party library you have to know the name or location
    of it, which is not typically portable, so here we use FFI::CheckLib's
    find_lib_or_die function. If the library is not found the script will
    die with a useful diagnostic. FFI::CheckLib has a number of useful
    features and will integrate nicely with Alien::Build based Aliens.

 The Win32 API with MessageBoxW

  Win32 API

    MessageBoxW function (winuser.h)
    <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxw>

  Perl Source

     use utf8;
     use FFI::Platypus 2.00;
     
     my $ffi = FFI::Platypus->new(
       api  => 2,
       lib  => [undef],
     );
     
     # see FFI::Platypus::Lang::Win32
     $ffi->lang('Win32');
     
     # Send a Unicode string to the Windows API MessageBoxW function.
     use constant MB_OK                   => 0x00000000;
     use constant MB_DEFAULT_DESKTOP_ONLY => 0x00020000;
     $ffi->attach( [MessageBoxW => 'MessageBox'] => [ 'HWND', 'LPCWSTR', 'LPCWSTR', 'UINT'] => 'int' );
     MessageBox(undef, "I ❤️ Platypus", "Confession", MB_OK|MB_DEFAULT_DESKTOP_ONLY);

  Execute

     $ perl win32_messagebox.pl

  Discussion

    The API used by Microsoft Windows presents some unique challenges. On
    32 bit systems a different ABI is used than what is used by the
    standard C library. It also provides a rats nest of type aliases.
    Finally if you want to talk Unicode to any of the Windows API you will
    need to use UTF-16LE instead of UTF-8 which is native to Perl. (The
    Win32 API refers to these as LPWSTR and LPCWSTR types). As much as
    possible the Win32 "language" plugin attempts to handle these
    challenges transparently. For more details see
    FFI::Platypus::Lang::Win32.

  Discussion

    The libnotify library is a desktop GUI notification system for the
    GNOME Desktop environment. This script sends a notification event that
    should show up as a balloon, for me it did so in the upper right hand
    corner of my screen.

 Structured Data Records (by pointer or by reference)

  C API

    cppreference - localtime
    <https://en.cppreference.com/w/c/chrono/localtime>

  Perl Source

     use FFI::Platypus 2.00;
     use FFI::C;
     
     my $ffi = FFI::Platypus->new(
       api => 2,
       lib => [undef],
     );
     FFI::C->ffi($ffi);
     
     package Unix::TimeStruct {
     
       FFI::C->struct(tm => [
         tm_sec    => 'int',
         tm_min    => 'int',
         tm_hour   => 'int',
         tm_mday   => 'int',
         tm_mon    => 'int',
         tm_year   => 'int',
         tm_wday   => 'int',
         tm_yday   => 'int',
         tm_isdst  => 'int',
         tm_gmtoff => 'long',
         _tm_zone  => 'opaque',
       ]);
     
       # For now 'string' is unsupported by FFI::C, but we
       # can cast the time zone from an opaque pointer to
       # string.
       sub tm_zone {
         my $self = shift;
         $ffi->cast('opaque', 'string', $self->_tm_zone);
       }
     
       # attach the C localtime function
       $ffi->attach( localtime => ['time_t*'] => 'tm', sub {
         my($inner, $class, $time) = @_;
         $time = time unless defined $time;
         $inner->(\$time);
       });
     }
     
     # now we can actually use our Unix::TimeStruct class
     my $time = Unix::TimeStruct->localtime;
     printf "time is %d:%d:%d %s\n",
       $time->tm_hour,
       $time->tm_min,
       $time->tm_sec,



( run in 1.852 second using v1.01-cache-2.11-cpan-bbb979687b5 )