読者です 読者をやめる 読者になる 読者になる

Perl - XSでDLLを呼び出す(その5)

今回は渡された実数を返すサブルーチンを実装する。

渡された実数を返す

引き数で指定された実数をそのまま返すサブルーチンをExample2.xsに追加で実装する。

NV
echo_nv(n)
INPUT:
    NV n;
CODE:
    RETVAL = n;
OUTPUT:
    RETVAL

以下の点がecho_ivサブルーチンと異なる。
戻り値のタイプは実数(Number Value)を表す "NV" である。
C言語の "double" と記述しても良い。
INPUTフィールドに記述する "n" のタイプは戻り値と同様に "NV" である。
やはり "double" と記述しても同じ実数を意味する。

テストのために以下のスクリプトを "c:\xs\Example2\TestEx2-2.pl" として保存する。

use ExtUtils::testlib;
use Example2;

print Example2::echo_nv(567) . "\n";
print Example2::echo_nv(890.12) . "\n";
print Example2::echo_nv(345.678) . "\n";
print Example2::echo_nv("901") . "\n";
print Example2::echo_nv("234.56") . "\n";
print Example2::echo_nv("789.012yen") . "\n";
print eval {Example2::echo_nv()};
print $@;
print eval {Example2::echo_nv(3, 4.5)};
print $@;

上記を実行した結果は以下の通りである。

567
890.12
345.678
901
234.56
789.012
Usage: Example2::echo_nv(n) at TestEx2-2.pl line 10.
Usage: Example2::echo_nv(n) at TestEx2-2.pl line 12.

結果は数値が実数として扱われていることを除いて、echo_ivサブルーチンとの違いはない。
Cファイルの内容はどうだろうか。

XS(XS_Example2_echo_nv)
{
    dXSARGS;
    if (items != 1)
        Perl_croak(aTHX_ "Usage: Example2::echo_nv(n)");
    {
        NV      n = (NV)SvNV(ST(0));
        NV      RETVAL;
        dXSTARG;
#line 27 "Example2.xs"
        RETVAL = n;
#line 155 "Example2.c"
        XSprePUSH; PUSHn((NV)RETVAL);
    }
    XSRETURN(1);
}

以下の点がecho_ivサブルーチンと異なる。
SvNVマクロはSTマクロの戻り値を実数に変換するようだ。
RETVAL変数はecho_nvサブルーチンの戻り値のタイプで定義されている。
PUSHnマクロは実数値をスタックに積むようだ。

次回は実数の代わりに文字列で試して見ようと思う。