'How to replace cpan Perl utility P5NCI with FFI:Platypus
Below is perl code which calls P5NCI::load_func to load function load_library having signature as int load_library(int dummy), hence third argument is passed as ii to P5NCI::load_func
my $library_path = P5NCI::find_lib( 'ESNMP.so' );
$library = P5NCI::load_lib( $library_path );
print "\nLibrary loaded";
print "\nlibrary_path".$library_path;
my $funcldlib = P5NCI::load_func( $library, 'load_library', 'ii');
This was working fine till perl-5.14, but later I used it for perl-5.26.3, but I am getting error as below:
Don't understand NCI signature 'ii'
I am thinking to use FFI platypus. I have successfully compiled Platypus using below steps:
perl -MCPAN -e shell
install FFI::Platypus
Wanted to know how can I use FFI::Platypus to achieve same purpose as mentioned in above code with P5NCI
Regards, Amit Mendhe
Solution 1:[1]
Here is an example of how you can use FFI::Platypus
and FFI::CheckLib
to do the same as you did with P5NCI
:
use feature qw(say);
use strict;
use warnings;
use FFI::Platypus;
use FFI::CheckLib;
my $libname = 'ESNMP';
my @libs = find_lib(lib => $libname, libpath => './lib');
die "Could not find libary '$libname'\n" if !@libs;
my $libpath = $libs[0];
my $ffi = FFI::Platypus->new();
$ffi->lib( $libpath );
my $function = $ffi->function('load_library', ['int'] => 'int');
my $input_value = 2;
my $return_value = $function->($input_value);
say "Return value: ", $return_value;
Note that this assumes that there is a file (the shared library) under the current directory called lib/libESNMP.so
. This was the path I used for testing this script. I also assume that there is a function called load_library()
defined in the shared library that takes an integer input argument and returns an integer.
Solution 2:[2]
The equivalent of
my $library_path = P5NCI::find_lib( 'ESNMP.so' );
my $library = P5NCI::load_lib( $library_path );
my $funcldlib = P5NCI::load_func( $library, 'load_library', 'ii' );
my $j = $funcldlib->( $i );
is
use FFI::Platypus qw( find_lib_or_die );
my $ffi = FFI::Platypus->new( api => 1 );
$ffi->lib( find_lib_or_die( lib => 'ESNMP' ) );
$ffi->attach( load_library => [ 'int' ] => 'int' );
my $j = load_library( $i );
This is copied almost verbatim from the module's documentation's synopsis. Please make an attempt to answer your own questions in the future.
Note that I find it very suspicious that a function called load_library
has an int
parameter. Is its parameter really an int
? A string seems more likely. But, it was declared as an int
in the P5NCI versions, so I declared it as an int
in the FFI::Platypus version.
Note that FFI will look for libESNMP.so
, but you appear to have an unconventionally-named library. You could use the very same function P5NCI used to find it instead of using find_lib_or_die
.
use Dynaloader qw( );
my $lib_path = DynaLoader::dl_findfile( 'ESNMP' )
or die( ... );
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |