The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

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 reinitialize
signature - string describing any parameters and return value
code - a code reference
userdata - optional, arbitrary data

dcbFreeCallback( ... )

Destroys and frees the callback.

    dcbFreeCallback( $pcb );

Expected parameters include:

pcb - Dyn::Callback object to reinitialize

dcbGetUserData( ... )

Returns the userdata passed to the callback object on creation or initialization.

    my $data = dcbGetUserData( $pcb );

Expected parameters include:

pcb - Dyn::Callback object to query

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>