我想寫暴露片庫,以 Perl代碼爲可寫入流接口一些XS碼。下面 get_stream
功能應該是 準備並返回一個PerlIO的對象的構造。我想我只需要 Write
和Close
方法,所以我留下了所有其他功能插槽的空白。爲什麼這個XS代碼返回一個PerlIO * leaky?
typedef struct {
struct _PerlIO base;
mylib_context* ctx;
} PerlIOmylib;
/* [...] */
PERLIO_FUNCS_DECL(PerlIO_mylib_funcs) = {
.fsize = sizeof(PerlIO_funcs),
.name = "mylib",
.size = sizeof(PerlIOmylib,
.Write = mylib_write,
.Close = mylib_close,
};
/* XS below */
PerlIO*
get_stream (SV* context_obj)
CODE:
mylib_context* ctx = (mylib_context*) SvIV (SvRV (context_obj));
PerlIO* f = PerlIO_allocate (aTHX);
f = PerlIO_push (aTHX, f, PERLIO_FUNCS_CAST(&PerlIO_mylib_funcs), "a", NULL);
PerlIOSelf(f, PerlIOmylib)->ctx = ctx;
PerlIOBase(f)->flags |= PERLIO_F_OPEN;
RETVAL = f;
OUTPUT:
RETVAL
當我這樣使用提供的接口...
{
my $fh = MyLib::get_stream($lib_ctx);
print $fh "x" x 300;
}
...的mylib_write
函數被調用,所以我還沒有完全 搞砸了這麼遠。 (我通過插入debug printf 語句驗證了這一點。)但是,當 $fh
超出範圍時,我想要關閉PerlIO對象,只需使用由open
創建的常規 文件句柄即可。但目前,只有在解釋器關閉期間調用該函數。
直接調用close
優良工程,設置$fh
到undef
不 沒有。
UPDATE:繼池上的建議下,我用Devel::Peek::Dump
和sv_dump
,發現手柄返回get_stream
功能是「RV」 指向一個SV = PVGV(...)
。 glob(PVGV
)的 引用計數器設置爲3,這看起來不正確。
我加入
CLEANUP:
SvREFCNT_dec (SvRV (ST(0)));
SvREFCNT_dec (SvRV (ST(0)));
其固化症狀:當$fh
在所述塊的端超出範圍的close
函數被調用。但我還是不太明白底層的問題。
ST(0) = sv_newmortal();
{
GV *gv = newGVgen("MyLib");
if (do_open(gv, "+<&", 3, FALSE, 0, 0, RETVAL))
sv_setsv(ST(0), sv_bless(newRV((SV*)gv), gv_stashpv("MyLib",1)));
else
ST(0) = &PL_sv_undef;
}
XSRETURN(1);
怎樣的GV的引用計數爲3結束了:
這是爲OUTPUT
部分生成C代碼?
微克,在同一職位在同一全新的問題 – ikegami