8

質問

XS 関数で自動有効化されたファイルハンドル引数をサポートするにはどうすればよいですか?

私はファイル記述子を返す C 関数を XS ラップしています。そのファイル記述子をopen()の方法でperl ファイルハンドル引数として提示したいと思います。例えば、

myfunc(my $fh) or die "Error: $!";
do_something_with_fh($fh);

これまでに行ったこと

現在、XS 関数の上に perl ラッパーを使用しています。

# -- in perl
sub myfunc {
    my $fd = _myfunc();
    return open($_[0], '+<&=', $fd) if defined($fd);
}

/* -- in XS */
SysRet
_myfunc()
    CODE:
    RETVAL = some_c_function_returning_an_fd();

    OUTPUT:
    RETVAL

これは Just Fine (tm) で動作しますが、ここでも、実装を完全に XS に移行したいと考えています。

これまでのところsv_2io、 として型マップされた引数を試してみましたSV *が、未定義のスカラーで例外がスローされます。最初の引数をFILE *orPerlIO *オブジェクトにマッピングしようとはしていません。なぜなら、これらのオブジェクトを "fdreopen" する方法がわからないからです。

4

1 に答える 1

3

私はmyfunc()ラッパーを Perl のままにしておきます。これは機能し、ボトルネックにはなりません。

再実装open()はトリッキーで、文書化されていない/内部 API を使用する必要があります。これはかなり近い実装だと思います。公開 API の一部ですが、文書化されておらずnewGVgen()変更される可能性があります。do_openn()

void
myfunc(sv)
    SV *sv
  PPCODE:
    {
        GV *gv = newGVgen("Mypackage");
        SV *rv = sv_2mortal(newRV_noinc((SV *)gv));
        SV *fd = sv_2mortal(newSViv(some_c_function_returning_an_fd()));

        if (!do_openn(gv, "+<&=", 4, FALSE, 0, 0, NULL, &fd, 1))
            croak("Could not fdopen descriptor: '%s'", Strerror(errno)); /* or XSRETURN_NO; */

        sv_setsv(sv, rv);
        SvSETMAGIC(sv);
        XSRETURN_YES;
    }
于 2013-01-06T20:14:09.617 に答える