以下最小示例定义PerlIO_write
周围的包装器:
MODULE = My::FH PACKAGE = My::FH
INCLUDE: const-xs.inc
int
write_fh (SV* fh, SV* str)
CODE:
STRLEN len
char* buf = SvPV(str, len);
PerlIO* io = IoIFP(sv_2io(fh));
if (io) {
RETVAL = PerlIO_write(io, buf, len);
} else {
croak("cannot use fh as a PerlIO handle");
}
OUTPUT:
RETVAL
在已创建的文件句柄上使用write_fh
函数
使用open $fh, '<', \$buf
按预期工作。但是,一个并列
使用以下代码段创建的文件句柄不会变为
PerlIO句柄:
my $fh = Symbol::gensym;
tie *$fh, 'My::TIEFH', \$buf;
My::TIEFH
包含所需的方法,并通过print
$fh $str
向其发送信息与预期一致。
从XS land写入绑定文件句柄需要做什么?
答案 0 :(得分:1)
print
使用call_method
在
PRINT
io && (mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar)))
是真的。放置在堆栈上的受祝福对象是
SvTIED_obj(MUTABLE_SV(io), mg)
顺便说一句,XS编译器可以在CODE
的内容之前放置非声明代码,因此CODE
的内容不能以声明开头。
CODE:
STRLEN len
char* buf = SvPV(str, len);
PerlIO* io = IoIFP(sv_2io(fh));
if (io) {
...
应该是
CODE:
{
STRLEN len
char* buf = SvPV(str, len);
PerlIO* io = IoIFP(sv_2io(fh));
if (io) {
...
}
或
PREINIT:
STRLEN len
char* buf = SvPV(str, len);
PerlIO* io = IoIFP(sv_2io(fh));
CODE:
if (io) {
...
答案 1 :(得分:0)
尝试理解print
中pp_hot.c
的定义后
并且阅读perlcall(3)
,我想出了以下内容
码。这有意义吗?
MODULE = My::FH PACKAGE = My::FH
INCLUDE: const-xs.inc
int
write_fh (SV* fh, SV* str)
INIT:
STRLEN len;
char* buf = SvPV(str, len);
PerlIO* pio = IoIFP(sv_2io(fh));
CODE:
if (pio) {
RETVAL = PerlIO_write(pio, buf, len);
} else {
if (!SvROK(fh))
croak("fh is not a reference");
IO* io = GvIO(SvRV(fh));
if (io == NULL)
croak("fh is not a GLOB reference");
MAGIC* mg = SvTIED_mg((const SV*)io, PERL_MAGIC_tiedscalar);
if (mg == NULL)
croak("fh is not a tied filehandle");
SV* obj = SvTIED_obj(MUTABLE_SV(io), mg);
if (obj == NULL)
croak("???");
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(obj);
XPUSHs(str);
PUTBACK;
RETVAL = call_method("PRINT", G_SCALAR);
if (i != 1)
croak("wrong number of return values (%i)", RETVAL);
SPAGAIN;
RETVAL=POPi;
PUTBACK;
FREETEMPS;
LEAVE;
}
OUTPUT:
RETVAL