【问题标题】:Support autovivified filehandle as arguments to Perl XS routine支持自动激活文件句柄作为 Perl XS 例程的参数
【发布时间】:2012-12-21 20:20:48
【问题描述】:

问题

如何在 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

这很好用 (tm),但是,我想再次将实现完全移到 XS 中。

到目前为止,我已经在类型映射为 SV * 的参数上尝试了 sv_2io,但这会在未定义的标量上引发异常。我没有尝试将第一个参数映射到 FILE *PerlIO * 对象,因为我不知道如何“fdreopen”(如果你愿意的话)这些对象。

【问题讨论】:

  • 也许看看自动生存模块search.cpan.org/dist/autovivification
  • 我没有看到任何从PerlIO 返回的PerlIO_fdopen 对象创建IO 对象的简单方法。 Perl 的open 背后的代码是自己完成的,而不是调用库函数。最终,您将调用 sv_replace(fh, rv) 将您创建的内容移动到参数中(给定 myfunc(SV* fh))。
  • @Rob,这是一个简洁的编译指示,但它并没有解决这里的问题。

标签: perl filehandle xs


【解决方案1】:

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

重新实现 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;
    }

【讨论】:

    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 2015-03-11
    • 2021-04-12
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多