从托管包装器重定向本机DLL stdout / stderr

时间:2014-04-18 17:25:30

标签: c# c++ redirect console pinvoke

我有一个C#控制台应用P/Invoke进入原生C++ dll。该DLL创建了一些非常繁琐的线程,并将其日志写入标准输出。问题是我需要Console来进行用户交互。

如何将dll stdout / stderr重定向到null

2 个答案:

答案 0 :(得分:2)

我认为,为了完成这项工作,您需要构建一个本机DLL,它链接到与麻烦的DLL相同的C ++运行时。然后,您需要使用freopen重定向标准输出。我的代码来源是这个答案:freopen: reverting back to original stream

C ++代码如下所示:

#include <io.h>

__declspec(dllexport) void RedirectStdOutputToNul(int *fd, fpos_t *pos)
{
    fflush(stdout);
    fgetpos(stdout, pos);
    *fd = _dup(fileno(stdout));
    freopen("NUL", "w", stdout);
}

__declspec(dllexport) void RestoreStdOutput(int fd, fpos_t pos)
{
    fflush(stdout);
    _dup2(fd, fileno(stdout));
    close(fd);
    clearerr(stdout);
    fsetpos(stdout, &pos);      
}

你可以从你的代码中调用它:

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern void RedirectStdOutputToNul(out int fd, out long pos);

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
static extern void RestoreStdOutput(int fd, long pos);

你可以这样称呼它:

int fd;
long pos;

RedirectStdOutputToNul(out fd, out pos);
print("boo");
RestoreStdOutput(fd, pos);
print("yah");

所有这些都依赖于链接到动态MSVC运行时的DLL,并且您能够编写链接到它的代码。

答案 1 :(得分:-2)

我对你的问题感到有些困惑,C#app是否会调用C ++,反之亦然?

无论哪种方式,我的回答都是相同的。将有问题的线程的输出传递到/ dev / null(虽然日志会更好......)

如果您可以控制c ++ dll,请使用: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx

否则: Redirecting standard input of console application

管道很棒。当我不想在终端上看到输出时,我经常将输出输出为空,而我不想记住如何导致静音运行。