Inline::Cで学ぶperlguts(その4)
最近、カオスCGの計算をしてるんだけど、そろそろCで書き直すフェーズなので、
なんとかInline::Cで解決できないかと思って、
今回は、配列リファレンスを返す方法を学んでみようと思う。
use v5.14;
use strict;
use warnings;
use Data::Dumper;
use Inline C => q{
SV * create_array_reference(SV *sv)
{
const IV n = SvIV( sv );
if ( n < 0 ) {
return &PL_sv_undef;
}
else {
AV *array = newAV();
for (IV i=0; i<n; i++) {
av_push( array, newSViv(i) );
}
return newRV_noinc( (SV *)array );
}
}
};
foreach ( 0, -1, 2 ) {
my $foo = create_array_reference( $_ );
if ( defined $foo ) {
say Dumper($foo);
}
else {
say 'undef!';
}
}
$ perl aaa.pl
$VAR1 = [];
undef!
$VAR1 = [
0,
1
];
整数はintでも良いのかなーって思いながらも、
とりあえず、IVを使ってみた。
I32とかの方が良いんですかね?
あと、戻り値の型がAV *だと、
&PL_sv_undefを返してもdefinedで思ったように判定できなくて、
それで戻り値の型をSV *に変更して、
newRV_incを使って配列リファレンスを返すようにした。
これなら、&PL_sv_undefを返してもdefinedで判定できた。
undefを返したい場合は、この辺を気にしないとダメっぽいですね。
追記 2016/02/09
newRV_noincでなければならないところで、newRV_incを使っていたので修正。
newRV_incで、引数の参照カウンタを余分にインクリメントしてた。
XSでメモリークを避けるたった一つの方法 – Islands in the byte stream
http://d.hatena.ne.jp/gfx/20100519/1274247355
次回は、こちらを参考にsv_2mortalを使ってみようと思う。
— ここまで追記 —
おしまい。
Leave a Comment