Заставить старую библиотеку работать с 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?
1 ответ
Perl API обеспечивает PerlIO_exportFILE()
( Реализация), которая может преобразовать дескриптор PerlIO с файловым дескриптором в stdio FILE
указатель. Поскольку PerlIO::Scalar является дескриптором файла "в памяти" без дескриптора файла, преобразование не может быть успешным. Единственный портативный способ передать PerlIO::Scalar
дескриптор будет сбрасывать его во временный файл. Менее переносимый способ - использовать stdio, поддерживающий обратные вызовы, такие как реализация BSD, funopen (3).