アンディのリンクから、Inline::C
approachを試してみてください。 AV*
ではなくSV*
を使用しますが、動作するはずです。
私はそのリンクに示されているメソッドを拡張して、例をあざ笑っています。 Cの限られた知識で、参照が何も指さなくなったときにSegfaultを防ぐことができたと思います。(内側の中括弧をコメント解除し、$テキストを範囲外にすることでテストします。 CセクションでnewRV_inc
を使用しているため、$text
の参照カウントが増分されます。したがって、$text
が範囲外になっていても、見つかった参照($recovered_ref
)がまだ存在する場合は、期待通りに値を使用できます(外側の中カッコのコメントを外してテストします)。
この方法は、どのような種類の参照でも機能するようです。オブジェクトについては不明ですが、必要ならばそれを行えます。詳細についてはperldoc Inline::C
が役に立ちますが、このパスを続けるには、perldoc perlguts
、さらにはperldoc perlapi
と読む必要があります。
#!/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;
}
関連:http://stackoverflow.com/questions/1671281/how-can-i-convert-the-stringified-version-of-array-reference-to-actual-array-refe。それはまさにARRAYについてのものだったので、それは偽りではありません。 – Andy
いいえ、参照はポインタではありません。どのように最初の場所で文字列になったのですか?それがバグです。 – shawnhcorey
@ shawnhcorey、いいえそれはポインタではありませんが、同じ情報が含まれています、私の答えを参照してください –