Plexus Plexus - 1 month ago 7
Perl Question

Pass function pointer as part of a hash, perl

The script runs such that THE USER defines some function:

sub userFunction
{
my ($msg, $id) = @ARG;
# do things
}


This function, $func is passed with a specific message name, $msg, into my class to be stored as a $msg/$userFunc pair in {_Handles}:

sub new
{
my ($class, ...) = @_;
my $self = {};
$self->{_Handles} = {};
.
.
.
}


Then I add a message handler:

$Class->AddMsgHandler($msgName1, \&userFunction);
sub AddMsgHandler
{
my ($self, $msg, $func) = @ARG;
my $funcPtr = $func->();
$self->{_Handles}{'msg'} = $msg;
$self->{_Handles}{$msg}{'funcPtr'} = $funcPtr;
}


The intention is to transfer my message wirelessly across a device; another device will receive this message. Assuming the device receives the message in another function, I'm trying to call the user defined function on specific $id as follows:

sub Receive
{
.
.
.
my $funcPtr = $self->{_Handles}{$msg}{'funcPtr'};
$funcPtr->($msg, $self->{_devices}{$id});
}


somehow there's no response. Perhaps I have misused the function pointer?

Answer

When you do this: my $funcPtr = $func->();, you're executing the subroutine and assigning the function's return value to $funcPtr, not the function's code reference itself, which I think is what you're after. You need to remove the ->() from that assignment. Here's a brief example:

use warnings;
use strict;

my %store;

sub user_func {
    return 5;
}
sub set {
    my $func = shift;
    $store{func} = $func;
}

set(\&user_func);

print $store{func}->();

Here's an example that shows the difference:

sub func {
    return 5;
}

my $cref = \&func;

my $called = $cref->();
my $not_called = $cref;

print "$called\n";
print "$not_called\n";

Output:

5
CODE(0x801c82ed0)
Comments