Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;暂时重定向或禁用stdio 在McOSX下的C++项目中,我们使用STDIO与客户机交互。然而,我们使用的动态库也使用stdio来打印“打开的日志文件”。这会中断客户端和应用程序之间的所有通信。我查看了将stdio重定向到文件或临时禁用stdio的示例。然而,我们不能在这方面取得成功_C++_Stdio - Fatal编程技术网

C++;暂时重定向或禁用stdio 在McOSX下的C++项目中,我们使用STDIO与客户机交互。然而,我们使用的动态库也使用stdio来打印“打开的日志文件”。这会中断客户端和应用程序之间的所有通信。我查看了将stdio重定向到文件或临时禁用stdio的示例。然而,我们不能在这方面取得成功

C++;暂时重定向或禁用stdio 在McOSX下的C++项目中,我们使用STDIO与客户机交互。然而,我们使用的动态库也使用stdio来打印“打开的日志文件”。这会中断客户端和应用程序之间的所有通信。我查看了将stdio重定向到文件或临时禁用stdio的示例。然而,我们不能在这方面取得成功,c++,stdio,C++,Stdio,所以,我们如何在和动态库交互时暂时禁用或重定向stdio呢 OSX是POSIX系统,与所有POSIX系统一样,标准输出是文件描述符STDOUT\u FILENO(定义为1的宏) 您可以做的是STDOUT\u FILENO到另一个文件描述符,一个临时文件,并将临时文件作为STDOUT\u FILENO复制(使用dup2)。然后,只要有输出到标准输出(使用普通代码>写< /COD>,C Prtff < /C> >或C++ STD::CUT),它将被放入临时文件中。 完成临时“重定向”后,只需将保存

所以,我们如何在和动态库交互时暂时禁用或重定向stdio呢

OSX是POSIX系统,与所有POSIX系统一样,标准输出是文件描述符
STDOUT\u FILENO
(定义为
1
的宏)

您可以做的是
STDOUT\u FILENO
到另一个文件描述符,一个临时文件,并将临时文件作为
STDOUT\u FILENO
复制(使用
dup2
)。然后,只要有输出到标准输出(使用普通代码>写< /COD>,C<代码> Prtff < /C> >或C++ <代码> STD::CUT),它将被放入临时文件中。

完成临时“重定向”后,只需将保存的标准输出(从第一次
dup
调用)复制回
STDOUT\u FILENO
。然后关闭并删除临时文件

如下所示:

int saved_stdout = dup(STDOUT_FILENO);

int temp_file = open("/tmp/temp_stdout", O_WRONLY, 0600);
dup2(temp_file, STDOUT_FILENO);  // Replace standard out

// Code here to write to standard output
// It should all end up in the file /tmp/temp_stdout

dup2(saved_stdout, STDOUT_FILENO);  // Restore old standard out
close(temp_file)
unlink("/tmp/temp_stdout");  // Remove file

重要的一点是从代码中识别在dylib中调用的函数。现在,请使用上述重定向和恢复功能围绕这些功能。

谢谢你,Joachim,我们尝试了你的建议。不幸的是,它仍然将“打开的日志文件”打印到stdio。谢谢sameerkn,我们尝试了这个解决方案。我们注意到,第一次运行代码时,“打开日志文件”文本从控制台中消失。但下一次,它仍然存在,并破坏了与客户端应用程序的通信。我认为您的方法可以处理所有三种使用stdio的情况;所以我希望它能工作。另外,如果我写
close(STDOUT\u FILENO)
fclose(标准输出)永远不会打印日志文本。有没有办法在事后恢复标准输出?
dup2
本身会关闭标准输出文件
重定向
功能中没有的文件。您是否正确地将对dylib的所有调用嵌套在
重定向
还原
函数下?下面是我调用函数的方式:`intioriginalstdin\u FILENO=-1;内部原始标准文件号=-1;内部原始文件号=-1;将标准流重定向到文件名(&iOriginalSTDIN\U文件号,&iOriginalSTDOUT\U文件号,&IORIGINALSTDER\U文件号);std::string a=listCardTypeAndSlots();恢复标准流(&iOriginalSTDIN_文件号,&iOriginalSTDOUT_文件号,&IORIGINALSTDER_文件号);标准::不能再多说一点。如果我在restore和std::cout之间暂停5秒,日志将在5秒后打印。因此,当我向std::cout写入一些非常简单的内容时,日志会写入控制台。
void RedirectStandardStreamsToDEVNULL(int *_piOriginalSTDIN_FILENO, int *_piOriginalSTDOUT_FILENO, int *_piOriginalSTDERR_FILENO)
{
        //flushing pending things before redirection.
        //fflush(stdin);
        fflush(stdout);
        fflush(stderr);

        *_piOriginalSTDIN_FILENO = dup(STDIN_FILENO);
        *_piOriginalSTDOUT_FILENO = dup(STDOUT_FILENO);
        *_piOriginalSTDERR_FILENO = dup(STDERR_FILENO);

        int devnull = open("/dev/null", O_RDWR);
        dup2(devnull, STDIN_FILENO);
        dup2(devnull, STDOUT_FILENO);
        dup2(devnull, STDERR_FILENO);
        close(devnull);
}
void RestoreStandardStreams(int *_piOriginalSTDIN_FILENO, int *_piOriginalSTDOUT_FILENO, int *_piOriginalSTDERR_FILENO)
{
        //flushing pending things before restoring.
        //fflush(stdin);
        fflush(stdout);
        fflush(stderr);

        dup2(*_piOriginalSTDIN_FILENO, STDIN_FILENO);
        dup2(*_piOriginalSTDOUT_FILENO, STDOUT_FILENO);
        dup2(*_piOriginalSTDERR_FILENO, STDERR_FILENO);
}

void myfunction()
{
    int iOriginalSTDIN_FILENO = -1;
    int iOriginalSTDOUT_FILENO = -1;
    int iOriginalSTDERR_FILENO = -1;
    RedirectStandardStreamsToDEVNULL(&iOriginalSTDIN_FILENO, &iOriginalSTDOUT_FILENO, &iOriginalSTDERR_FILENO);

//all of your code which prints to stdout or stderr will be directed to /dev/null

    RestoreStandardStreams(&iOriginalSTDIN_FILENO, &iOriginalSTDOUT_FILENO, &iOriginalSTDERR_FILENO);

}