さて、今度はもう少し込み入った例です。今回は、2 つの引数として、文字列
($a)
と整数 ($n)
をとる Perl sub を呼び出してみましょう。
では、簡単に、文字列の最初の $n 文字を出力します。
sub
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
の注意点を示します。
PUSHMARK
マクロと
PUTBACK
マクロで囲まなければなりません。この 2 つのマクロは、この
文脈では、自動的にプッシュした引数の数を数えるために使われます。それで、
Perl が sub に対して @_ 配列を作るときには、その大きさがわかると
いう仕組みになっているのです。
PUSHMARK
マクロは、Perl に対して、内的にその時点のスタックポイン
タに注目するように伝えます。(See section 例 1: パラメータなし、返却値なし,の場
合のように) 引数を渡さない場合であっても、 perl_call_*
関数を呼ぶ
場合には、その前に PUSHMARK
マクロを呼ばなくてはなりません。Perl
からすると、引数がないことを知る必要があるのです。
少し先へ飛んで、 PUTBACK
マクロは、グローバルなスタックポインタを、
先に作ったローカルなものに合わせます。これを行わないと、どこに引数を置い
たか、 perl_call_pv
が判断することができません。ここまで、すべて
のスタックポインタの操作は、ローカルなものに対して行なってきたのであって、
グローバルなものは触っていなかったのです。
XPUSH
を引数分呼んでいます。ここで、実際に引数が
スタックに積まれます。今回の場合、文字列と整数を積んでいます。
XPUSH
マクロがどのように動作するのかについて詳しくは、
See section 拡張を行なうための内部関数,の「See section XSUB と引数スタック,」の項を
参照してください。
LeftString
を perl_call_pv
関数を介して呼ぶこ
とができます。
Go to the first, previous, next, last section, table of contents.