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


例 6: G_EVAL を使う

今度は G_EVAL を使う例です。以下は、2 つの引数の差を計算する Perl sub です。結果が負になると、sub は die を呼びます。

sub Subtract
{
    my ($a, $b) = @_ ;
    die "death can be fatal\n" if $a < $b ;

    $a - $b ;
}

これを呼ぶ C の方は、

static void
call_Subtract(a, b)
int a ;
int b ;
{
    dSP ;
    int count ;
    SV * sv ;

    ENTER ;
    SAVETMPS;

    PUSHMARK(sp) ;
    XPUSHs(sv_2mortal(newSViv(a)));
    XPUSHs(sv_2mortal(newSViv(b)));
    PUTBACK ;

    count = perl_call_pv("Subtract", G_EVAL|G_SCALAR);

    /* Check the eval first */
    sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV));
    if (SvTRUE(sv))
        printf ("Uh oh - %s\n", SvPV(sv, na)) ;

    SPAGAIN ;

    if (count != 1)
        croak ("call_Subtract : expected 1 return "
                  "value from 'Subtract', got %d\n", count) ;

    printf ("%d - %d = %d\n", a, b, POPi) ;

    PUTBACK ;
    FREETMPS ;
    LEAVE ;

}

となります。call_Subtract

call_Subtract(4, 5)

のように呼ばれると、以下のように表示されます。

Uh oh - death can be fatal

注意点

  1. die を捉えるために、 G_EVAL フラグを使用しました。このフラ グを使用しないと、プログラムは途中終了してしまいます。
  2. C 関数の中の
    sv = GvSV(gv_fetchpv("@", TRUE, SVt_PV));
    if (SvTRUE(sv))
        printf ("Uh oh - %s\n", SvPVx(sv, na)) ;
    
    という部分は、Perl の書くところの
    print "Uh oh - $@\n" if $@ ;
    
    と同じことになります。


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

検索式: