Alt-FFI-libffi
view release on metacpan or search on metacpan
lib/FFI/Library.pm view on Meta::CPAN
package FFI::Library;
use strict;
use warnings;
use Carp ();
use constant _is_win => $^O =~ /^(MSWin32|cygwin|msys2?)$/;
# ABSTRACT: Perl Access to Dynamically Loaded Libraries
our $VERSION = '0.09'; # VERSION
sub new
{
my($class, $libname, $flags) = @_;
Carp::croak('Usage: $lib = FFI::Library->new($filename [, $flags ])')
unless @_ <= 3;
$flags ||= 0;
if(! defined $libname)
{
return bless {
impl => 'null',
}, $class;
}
elsif(ref $libname and int($libname) == int(\$0))
{
return $class->_dl_impl(undef, undef);
}
elsif(_is_win)
{
return $class->_dl_impl($libname, undef);
}
elsif(-e $libname)
{
return $class->_dl_impl(
$libname,
$flags == 0x01 ? FFI::Platypus::Lang::DL::RTLD_GLOBAL() : undef,
);
}
else
{
require DynaLoader;
my $so = DynaLoader::dl_findfile($libname) || $libname;
my $handle = DynaLoader::dl_load_file($so, $flags || 0);
return unless $handle;
return bless {
impl => 'dynaloader',
handle => $handle,
}, $class;
}
}
sub _dl_impl
{
my($class, $path, $flags) = @_;
require FFI::Platypus::DL;
$flags = FFI::Platypus::DL::RTLD_PLATYPUS_DEFAULT()
unless defined $flags;
my $handle = FFI::Platypus::DL::dlopen($path, $flags);
return unless defined $handle;
bless { impl => 'dl', handle => $handle }, $class;
}
sub address
{
my($self, $name) = @_;
if($self->{impl} eq 'dl')
{
return FFI::Platypus::DL::dlsym($self->{handle}, $name);
}
elsif($self->{impl} eq 'dynaloader')
{
return DynaLoader::dl_find_symbol($self->{handle}, $name);
}
elsif($self->{impl} eq 'null')
{
return;
}
else
{
Carp::croak("Unknown implementaton: @{[ $self->{impl} ]}");
}
}
sub function
{
my($self, $name, $sig) = @_;
my $addr = $self->address($name);
Carp::croak("Unknown function $name")
unless defined $addr;
require FFI;
sub { FFI::call($addr, $sig, @_) };
}
sub DESTROY
{
my($self) = @_;
if($self->{impl} eq 'dl')
{
FFI::Platypus::DL::dlclose($self->{handle});
}
elsif($self->{impl} eq 'dynaloader')
{
DynaLoader::dl_free_file($self->{handle})
if defined &DynaLoader::dl_free_file;
}
elsif($self->{impl} eq 'null')
{
# do nothing
}
else
{
Carp::croak("Unknown implementaton: @{[ $self->{impl} ]}");
}
}
( run in 2.254 seconds using v1.01-cache-2.11-cpan-75ffa21a3d4 )