Go to the first, previous, next, last section, table of contents.


例 2: パラメータを渡す

さて、今度はもう少し込み入った例です。今回は、2 つの引数として、文字列 ($a) と整数 ($n) をとる Perl sub を呼び出してみましょう。 sub では、簡単に、文字列の最初の $n 文字を出力します。

Perl sub は以下のようなものです:

sub LeftString
{
    my($s, $n) = @_ ;
    print substr($s, 0, $n), "\n" ;
}

`LeftString' を呼ぶための C の関数は、以下のようです:

static void
call_LeftString(a, b)
char * a ;
int b ;
{
    dSP ;

    PUSHMARK(sp) ;
    XPUSHs(sv_2mortal(newSVpv(a, 0)));
    XPUSHs(sv_2mortal(newSViv(b)));
    PUTBACK ;

    perl_call_pv("LeftString", G_DISCARD);
}

C の関数 call_LeftString の注意点を示します。

  1. 今回指定しているフラグは、G_DISCARD のみです。今回、Perl sub に 2 つのパ ラメータを渡しますので、G_NOARGS は指定していません。
  2. パラメータは、Perl スタックを使って Perl sub に渡されます。これが、dSP で始め、PUTBACK 行で終わるコードの目的です。
  3. Perl スタックに何かをおこうとする場合には、どこにおけばよいかを知る必要 があります。これが、マクロ dSP の目的で、Perl スタックポインタのローカル なコピーを宣言し、初期化します。 この例で使う、他のすべてのマクロは、このマクロの使用を前提にしています。 Perl sub を直接 XSUB 関数から呼ぶときには、明示的に dSPマクロを使う必要 はありません。自動的に宣言されます。
  4. スタック上に積まれるパラメータはすべて、 PUSHMARK マクロと PUTBACK マクロで囲まなければなりません。この 2 つのマクロは、この 文脈では、自動的にプッシュした引数の数を数えるために使われます。それで、 Perl が sub に対して @_ 配列を作るときには、その大きさがわかると いう仕組みになっているのです。 PUSHMARK マクロは、Perl に対して、内的にその時点のスタックポイン タに注目するように伝えます。(See section 例 1: パラメータなし、返却値なし,の場 合のように) 引数を渡さない場合であっても、 perl_call_* 関数を呼ぶ 場合には、その前に PUSHMARK マクロを呼ばなくてはなりません。Perl からすると、引数がないことを知る必要があるのです。 少し先へ飛んで、 PUTBACK マクロは、グローバルなスタックポインタを、 先に作ったローカルなものに合わせます。これを行わないと、どこに引数を置い たか、 perl_call_pv が判断することができません。ここまで、すべて のスタックポインタの操作は、ローカルなものに対して行なってきたのであって、 グローバルなものは触っていなかったのです。
  5. 元に戻って、次に XPUSH を引数分呼んでいます。ここで、実際に引数が スタックに積まれます。今回の場合、文字列と整数を積んでいます。 XPUSH マクロがどのように動作するのかについて詳しくは、 See section 拡張を行なうための内部関数,の「See section XSUB と引数スタック,」の項を 参照してください。
  6. ここまでで、 LeftStringperl_call_pv 関数を介して呼ぶこ とができます。


Go to the first, previous, next, last section, table of contents.

検索式: