我是一个XS初学者,我正在考虑改变现有的XS模块,该模块大量使用了15年以上的底层C库(实际上该模块基本上只是粘在这个库上)。问题是,我希望能够使用PerlIO字符串技巧,如:
open($fh, '<', $string);
,然后将$fh
传递给库期望FILE
的XS胶水。问题是XS有:
int
_parse (entry_ref, filename, file, preserve=FALSE)
SV * entry_ref;
char * filename;
FILE * file;
boolean preserve;
,我假设它需要是:
PerlIO * file;
这当然不起作用,因为肯定有更多的原因。当我查看库中的_parse
代码时,它最终出现在:
AST * bt_parse_entry (FILE * infile,
char * filename,
btshort options,
boolean * status)
{
AST * entry_ast = NULL;
static int * err_counts = NULL;
static FILE * prev_file = NULL;
再次表示FILE
类型。现在我要开始的基本问题是不改变库是否可能;也就是说,我可以通过改变XS从字符串PerlIO行为获得伪文件句柄吗?
Perl API提供PerlIO_exportFILE()
(Implementation),它可以将带有文件描述符的PerlIO句柄转换为stdio FILE
指针。由于PerlIO::Scalar是一个没有文件描述符的"内存中"文件句柄,因此转换无法成功。传递PerlIO::Scalar
句柄的唯一可移植方法是将其刷新到临时文件中。可移植性较差的方法是使用支持回调的工作室,如BSD实现,funopen(3)。