C 中的嵌入式 perl、perlapio - 与 STDIO 的互操作性

2024-03-18

我刚刚意识到,PerlIO 层似乎不仅仅(或多或少)轻松地包装 stdio.h 函数。 如果我尝试使用通过以下方式解析的文件描述符PerlIO_stdout() and PerlIO_fileno()对于 stdio.h 中的函数,这会失败。

例如:

PerlIO* perlStdErr = PerlIO_stderr();
fdStdErrOriginal = PerlIO_fileno(perlStdErr);
relocatedStdErr = dup(fdStdOutOriginal);
_write(relocatedStdErr, "something", 8); //<-- this fails

我用VC10试过了。嵌入式 Perl 程序是从不同的上下文执行的 - 因此不可能从执行对 relocatedStdErr 的写入的上下文中使用 PerlIO。

出于好奇:我需要执行一个 perl 脚本并将脚本的 stdout/stderr 的输出转发到日志,同时保留自己在 stdout 上写入的能力。此外,这应该独立于平台工作(Linux、Windows 控制台应用程序、win32 桌面应用程序)。只是转发 stdout/stderr 在 Win32 桌面应用程序中不起作用,因为没有 ;) - 您需要使用 perl 的 stdout/stderr。

所需的解决方案:能够在从 perlio 派生的文件句柄(或描述符)上进行写入,而不是使用 PerlIO 堆栈。

编辑-我的解决方案:

当 Story Teller 指向 PerlIO_findFILE 时,这就成功了。 所以这里是代码的摘录 - 请参阅里面的注释以获取描述:

FILE* stdErrFILE = PerlIO_findFILE(PerlIO_stderr()); //convert to Perl's stderr to stdio FILE handle

fdStdErrOriginal = _fileno(stdErrFILE); //get descriptor using MSVC

if (fdStdErrOriginal >= 0)
{
    relocatedStdErr = _dup(fdStdErrOriginal); //relocate stdErr for external writing using MSVC
    if (relocatedStdErr >= 0)
    {
        if (pipe(fdPipeStdErr) == 0) //create pipe for forwarding stdErr - USE PERL's IO since win32subsystem(non-console) "_pipe" doesn't work
        {
            if (dup2(fdPipeStdErr[1], fdStdErrOriginal) >= 0) //hang pipe on stdErr - USE PERL's IO (since it's created by perl)
            {
                close(fdPipeStdErr[1]); //close the now duplicated writer on stdErr for further usage - USE PERL's IO (since it's created by perl)
                //"StreamForwarder" creates a thread that catches/reads the pipe's input and forwards it to the processStdErrOutput function (using the PerlIO)
                stdErrForwarder = new StreamForwarder(fdPipeStdErr[0], &processStdErrOutput, PerlIO_stderr()); 
                return relocatedStdErr; //return the relocated stdErr to be able to '_write' onto it
            }
        }
    }
}
...
...
    _write(relocatedStdErr, "Hello Stackoverflow!", 20); //that works :)

我实际上不明白的一件有趣的事情是,perl 文档说没有必要#define PERLIO_NOT_STDIO 0能够使用PerlIO_findFILE()。但对我来说,没有它也能正常工作,而且我喜欢将 PerlIO 和 stdio 一起使用。这是我没有弄清楚发生了什么事情的一点。


None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 中的嵌入式 perl、perlapio - 与 STDIO 的互操作性 的相关文章

随机推荐