Как заставить старую библиотеку работать с Perl XS и PerlIO

Я скорее новичок в XS, и я изучаю возможность изменения существующего модуля XS, который интенсивно использует базовую библиотеку C 15-летней давности (на самом деле модуль в основном просто приклеивается к этой библиотеке). Проблема в том, что я хотел бы иметь возможность использовать строковые трюки PerlIO, например:

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

а затем передайте $fh в клей XS, где библиотека ожидает FILE. Проблема в том, что 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 типами. Теперь основной вопрос, с которого я должен начать, - возможно ли это вообще без изменения библиотеки; то есть, могу ли я получить псевдо-файловый дескриптор из поведения строк PerlIO, просто изменив XS?


person PLK    schedule 05.06.2013    source источник


Ответы (1)


API Perl предоставляет PerlIO_exportFILE() (Реализация), который может преобразовать дескриптор PerlIO с дескриптором файла в stdio FILE указатель. Поскольку PerlIO::Scalar является дескриптор файла «в памяти» без дескриптора файла преобразование не может быть успешным. Единственный переносимый способ передать дескриптор PerlIO::Scalar — это сбросить его во временный файл. Менее переносимым способом было бы использование stdio, который поддерживает обратные вызовы, например реализацию BSD, funopen(3).

person chansen    schedule 09.06.2013