Making an old library work with Perl XS and PerlIO
Asked Answered
A

1

8

I am rather an XS beginner and I am looking into changing an existing XS module which uses a 15+ year old underlying C library heavily (in fact the module is basically just glue to this library). The problem is that I would like to be able to use PerlIO string trickery like:

open($fh, '<', \$string);

and then pass $fh to the XS glue where the library is expecting FILE. The problem is that the XS has:

int
_parse (entry_ref, filename, file, preserve=FALSE)
    SV *    entry_ref;
    char *  filename;
    FILE *  file;
    boolean preserve;

and I assume that it needs to be:

PerlIO *  file;

This doesn't work of course as there must be more to it than that. When I look at the _parse code in the library, it ends up in:

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;

with FILE types again. Now the basic question I have have to start with is - is this even possible without changing the library; that is, can I get pseudo-filehandle from strings PerlIO behaviour just by changing the XS?

Adenectomy answered 5/6, 2013 at 8:59 Comment(0)
C
3

The Perl API provides PerlIO_exportFILE() (Implementation) which can convert a PerlIO handle with a file descriptor to a stdio FILE pointer. Since PerlIO::Scalar is an "in-memory" file handle without a file descriptor the conversion cannot succeed. The only portable way to pass a PerlIO::Scalar handle would be to flush it to a temporary file. The less portable way would be to use a stdio that supports callbacks, like the BSD implementation, funopen(3).

Clastic answered 9/6, 2013 at 20:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.