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