Inline::Cで学ぶperlguts(その7)

Chaotic for iOSは、Perlでプロトタイプを書いてSwiftに書き直したものですが、
書き直す過程で行った変更をフィードバックするのに、調べごとをしたのでメモ。

use v5.14;
use strict;
use warnings;
use Data::Dumper;

use Inline C => q{
    #include <stdio.h>

    SV * foo(SV *dst)
    {
        if ( SvROK(dst) == 0 ) {
            printf( "error!\n" );
            return newSViv( 0 );
        }

        AV *points = (AV *)SvRV( dst );
        const int32_t n = av_len(points) + 1;
        printf( "n = %d\n", n );

        SV **base = AvARRAY( points );
        for (int32_t i=0; i<n; i++) {
            if ( SvROK(base[i]) == 0 ) {
                printf( "error!\n" );
                return newSViv( 0 );
            }

            AV *point = (AV *)SvRV( base[i] );
            sv_setnv( *av_fetch(point, 0, TRUE), (NV)(i * 2 + 0) );
            sv_setnv( *av_fetch(point, 1, TRUE), (NV)(i * 2 + 1) );
        }

        return newSViv( 1 );
    }
};

my @points = map {
    #  x,  y
    [ -1, -1 ]
} 1..3;

say Dumper( @points );
say "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=";
foo( \@points );
say "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=";
say Dumper( @points );

実行するとこんな感じ。

$ perl aaa.pl
$VAR1 = [
          -1,
          -1
        ];
$VAR2 = [
          -1,
          -1
        ];
$VAR3 = [
          -1,
          -1
        ];

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
n = 3
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
$VAR1 = [
          '0',
          '1'
        ];
$VAR2 = [
          '2',
          '3'
        ];
$VAR3 = [
          '4',
          '5'
        ];

やりたいことは、あらかじめ確保した領域に対して、
なんらかの処理を行った結果を格納すること。
Perlもそうだけど、
要素数は確保済みの配列から取得できるので、
出力先だけ渡して、そこに格納する方法を調べてみた。

ただ、xとyというメンバーを持つ構造体みたいなケースだと、
いつもはハッシュ(*1)で対応するんだけど、それはちょっと面倒だったので、
今回は配列にリストを入れて、そのリファレンスを引数に渡すことにした。

けっこう、かしこくなったんじゃないですかね!

おしまい。

(*1) 連想配列のことをハッシュって呼ぶ言語はかなり限定されるらしいですね。

Leave a Comment