Dyn::Callback - Perl Code as FFI Callbacks
use Dyn::Callback qw[:all]; use Dyn::Load; use Dyn::Call qw[DC_CALL_C_DEFAULT]; my $lib = Dyn::Load::dlLoadLibrary('path/to/lib.so'); my $ptr = Dyn::Load::dlFindSymbol( $lib, 'timer' ); my $cvm = dcNewCallVM(1024); Dyn::Call::dcMode( $cvm, DC_CALL_C_DEFAULT ); Dyn::Call::dcReset($cvm); my $cb = dcbNewCallback( # Accepts an int and returns an int 'i)i', sub { my ($cb, $args, $result, $userdata) = @_; ...; # do something return 'i'; }, 5 ); Dyn::Call::dcArgPointer( $cvm, $cb ); # pass callbacks as pointers Dyn::Call::dcCallVoid( $cvm, $ptr ); # your timer() function returns void
Dyn::Callback is an interface to create callback objects that can be passed to functions as callback arguments. In other words, a pointer to the callback object can be "called" directly from the foreign library.
These may be imported by name or called directly.
dcbNewCallback( $signature, $coderef, $userdata )
Creates a new callback object, where $signature is a signature string describing the function.
$signature
my $pcb = dcbNewCallback( 'i)i', sub { my ($cb, $args, $result, $userdata) = @_; ...; return 'i'; }, 5 );
Expected parameters include:
signature
This is needed for dyncallback dyncallback to correctly prepare the arguments passed in by the function that calls the callback handler.
code
Note that the code reference doesn't return the value specified in the signature, directly, but a signature character, specifying the return value's type. The return value itself is stored where the callback's 3rd parameter points to (see below).
userdata
This data, if defined, is passed back to the given coderef as the 4th parameter.
dcbInitCallback( ... )
Initialize (or reinitialize) the callback object.
dcbInitCallback( $pcb, 'i)Z', sub { ...; }, undef );
pcb
dcbFreeCallback( ... )
Destroys and frees the callback.
dcbFreeCallback( $pcb );
dcbGetUserData( ... )
Returns the userdata passed to the callback object on creation or initialization.
my $data = dcbGetUserData( $pcb );
Let's say, we want to create a callback object and call it. For simplicity, this example will omit passing it as a function pointer to a function in a separate library and demonstrate calling it directly. First, we need to define our callback handler:
sub cbHandler { my ( $cb, $args, $result, $userdata ) = @_; # $cb is a Dyn::Callback object # $args is a Dyn::Callback::Args object # $result is a Dyn::Callback::Value object # $userdata, if defined, is a normal Perl value my $arg1 = dcbArgInt($args); my $arg2 = dcbArgFloat($args); my $arg3 = dcbArgShort($args); my $arg4 = dcbArgDouble($args); my $arg5 = dcbArgLongLong($args); # do something here $result->s(1244); return 's'; }
Note that the return value of the handler is a signature character, not the actual return value, itself. Now, let's call it through a Dyn::Callback object:
my $userdata = 1337; my $cb = dcbNewCallback( 'ifsdl)s', \&cbHandler, $userdata ); my $result = $cb->call( 123, 23, 3, 1.82, 9909 ); # $result is 1244 dcbFreeCallback($cb);
Copyright (C) Sanko Robinson.
This library is free software; you can redistribute it and/or modify it under the terms found in the Artistic License 2. Other copyrights, terms, and conditions may apply to data transmitted through this module.
Sanko Robinson <sanko@cpan.org>
To install Affix, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Affix
CPAN shell
perl -MCPAN -e shell install Affix
For more information on module installation, please visit the detailed CPAN module installation guide.