NAME
Dyn::Callback - Perl Code as FFI Callbacks
SYNOPSIS
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
DESCRIPTION
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.
Functions
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.
my $pcb = dcbNewCallback(
'i)i',
sub {
my ($cb, $args, $result, $userdata) = @_;
...;
return 'i';
},
5
);
Expected parameters include:
signature
- string describing any parameters and return value-
This is needed for dyncallback dyncallback to correctly prepare the arguments passed in by the function that calls the callback handler.
code
- a code reference-
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
- optional, arbitrary data-
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 );
Expected parameters include:
pcb
- Dyn::Callback object to reinitializesignature
- string describing any parameters and return valuecode
- a code referenceuserdata
- optional, arbitrary data
dcbFreeCallback( ... )
Destroys and frees the callback.
dcbFreeCallback( $pcb );
Expected parameters include:
dcbGetUserData( ... )
Returns the userdata passed to the callback object on creation or initialization.
my $data = dcbGetUserData( $pcb );
Expected parameters include:
Example
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);
LICENSE
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.
AUTHOR
Sanko Robinson <sanko@cpan.org>