支持autovivified文件句柄作为Perl XS例程的参数

时间:2012-12-21 20:20:48

标签: perl filehandle xs

问题

如何在XS函数中支持自动生成的文件句柄参数?

我是XS包装一个返回文件描述符的C函数,我想以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 *PerlIO *对象,因为我不知道如何“fdreopen”(如果你愿意)这些对象。

1 个答案:

答案 0 :(得分:2)

我会将myfunc()包装器保留在Perl中,它可以工作,不应该成为瓶颈。

重新实现open()非常棘手,需要使用未记录的/内部API。我认为这是一个非常接近的实现。 newGVgen()do_openn()是公共API的一部分,但未记录且subject to change

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;
    }