From the link given by Andy, try the Inline::C
approach. You will want to use SV*
rather than AV*
, but it should work.
I have mocked up an example, extending the method shown in that link. With my limited knowledge of C I think I have prevented a Segfault when the reference no longer points to anything (test by un-commenting the inner braces, allowing $text to fall out of scope). Because I use newRV_inc
in the C section, the reference count for $text
is incremented. Therefore if $text
falls out of scope, but its found reference ($recovered_ref
) still exists, the value is still available, as expected (test by un-commenting the outer braces).
This method would seem to work for any type of reference. Not sure about objects, give it a go if you want. For more info perldoc Inline::C
will help, but you will need to read perldoc perlguts
and possibly even perldoc perlapi
to continue down this path.
#!/usr/bin/perl
use strict;
use warnings;
use Inline 'C';
my $stringified_ref_text;
my $stringified_ref_array;
my $recovered_ref_text;
my $recovered_ref_array;
#{
#{
my $text = "Hello World";
my @array = qw"Hello World!";
$stringified_ref_text = \$text . "";
$stringified_ref_array = \@array . "";
print $stringified_ref_text . "\n";
print $stringified_ref_array . "\n";
#}
$recovered_ref_text = recover_ref($stringified_ref_text);
$recovered_ref_array = recover_ref($stringified_ref_array);
#}
print $$recovered_ref_text . "\n";
print "$_\n" for @$recovered_ref_array;
sub recover_ref {
my $input = shift;
my $addr;
if ($input =~ /0x(\w+)/) {
$addr = hex($1);
} else {
warn "Could not find an address";
return undef;
}
my $ref = _recover_ref($addr) or undef;
return $ref;
}
__DATA__
__C__
SV* _recover_ref(int address) {
if (address)
return newRV_inc((SV*) address);
return 0;
}