Alt-FFI-libffi

 view release on metacpan or  search on metacpan

lib/FFI.pm  view on Meta::CPAN

# ABSTRACT: Perl Foreign Function Interface based on libffi
our $VERSION = '0.09'; # VERSION

our $ffi = FFI::Platypus->new;
$ffi->lib(undef);

my $stdcall_ffi = _is_win32
  ? do {
    my $ffi = FFI::Platypus->new;
    $ffi->lib(undef);
    $ffi->abi('stdcall');
  }
  : $ffi;

our %typemap = qw(
  c   char
  C   uchar
  s   short
  S   ushort
  i   int
  I   uint
  l   long
  L   ulong
  f   float
  d   double
  p   string
  v   void
  o   opaque
);

sub _ffi
{
  if($_[0] =~ s/^([sc])//)
  {
    return $stdcall_ffi if $1 eq 's';
  }
  else
  {
    Carp::croak("first character of signature must be s or c");
  }
  
  $ffi;
}

sub call
{
  my $addr = shift;
  my $signature = shift;
  my $ffi = _ffi($signature);
  my($ret_type, @args_types) = map { $typemap{$_} } split //, $signature;
  $ffi->function($addr => \@args_types => $ret_type)->call(@_);
}

sub callback
{
  my($signature, $sub) = @_;
  my $ffi = _ffi($signature);
  my($ret_type, @args_types) = map { $typemap{$_} } split //, $signature;
  my $type = '(' . join(',', @args_types) . ')->' . $ret_type;
  my $closure = $ffi->closure($sub);
  bless {
    addr    => $ffi->cast($type => 'opaque', $closure),
    sub     => $sub,
    closure => $closure,
  }, 'FFI::Callback';
}

package FFI::Callback;

sub addr { shift->{addr} }

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

FFI - Perl Foreign Function Interface based on libffi

=head1 VERSION

version 0.09

=head1 SYNOPSIS

    use FFI;
    $addr = <address of a C function>
    $signature = <function signature>
    $ret = FFI::call($addr, $signature, ...);

    $cb = FFI::callback($signature, sub {...});
    $ret = FFI::call($addr, $signature, $cb->addr, ...);

=head1 DESCRIPTION

B<NOTE>: Newer and better maintained FFI modules such as L<FFI::Platypus>
provide more functionality and so it is strongly recommend that you use
one of them for new projects and even consider migrating to one of
them for existing projects.

This module provides a low-level foreign function interface to Perl. It 
allows the calling of any function for which the user can supply an 
address and calling signature. Furthermore, it provides a method of 
encapsulating Perl subroutines as callback functions whose addresses can 
be passed to C code.

=head1 FUNCTIONS

=head2 call

 my $ret = FFI::call($address, $signature, @arguments);

Call the function at the given C<$address> with the given C<$signature>>
(see below) and the given C<@arguments>.

=head2 callback



( run in 1.659 second using v1.01-cache-2.11-cpan-39bf76dae61 )