如何将stdout重定向到Windows应用程序中的某些可见显示?

Joe*_*ieg 37 c c++ windows user-interface stdout

我可以访问一个"好东西"的第三方库.它向stdout发出状态和进度消息.在控制台应用程序中,我可以很好地看到这些消息.在Windows应用程序中,他们只是转到位桶.

有没有一种相当简单的方法将stdout和stderr重定向到文本控件或其他可见的位置.理想情况下,这不需要重新编译第三方代码.它只是在低水平拦截蒸汽.我想要一个解决方案,我只需#include标头,调用初始化函数并链接库,如...

#include "redirectStdFiles.h"

void function(args...)
{
  TextControl* text = new TextControl(args...);
  initializeRedirectLibrary(text, ...);

  printf("Message that will show up in the TextControl\n");
  std::cout << "Another message that also shows up in TextControl\n";
}
Run Code Online (Sandbox Code Playgroud)

更好的是,如果它使用了一些我可以覆盖的接口,那么它就不会绑定到任何特定的GUI库.

class StdFilesRedirector
{
  public:
    writeStdout(std::string const& message) = 0;
    writeStderr(std::string const& errorMessage) = 0;
    readStdin(std::string &putReadStringHere) = 0;
};
Run Code Online (Sandbox Code Playgroud)

我只是在做梦吗?或者有人知道可以做这样的事情吗?

在两个答案后编辑:我认为使用freopen重定向文件是一个很好的第一步.要获得完整的解决方案,需要创建一个新线程来读取文件并显示输出.对于调试,在cygwin shell窗口中执行'tail -f'就足够了.对于更精美的应用程序...我想写的是什么......创建线程会有一些额外的工作,等等.

n0r*_*0rd 18

您需要创建管(带CreatePipe() ),然后将其附加标准输出到它与写结束SetStdHandle() ,那么你可以从管道与读端读的ReadFile() ,把你从那里您想要的位置获取文本.


Bri*_*ndy 16

您可以使用freopen重定向stdout,stderr和stdin .

从以上链接:

/* freopen example: redirecting stdout */
#include <stdio.h>

int main ()
{
  freopen ("myfile.txt","w",stdout);
  printf ("This sentence is redirected to a file.");
  fclose (stdout);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

您也可以通过命令提示符运行程序,如下所示:

a.exe > stdout.txt 2> stderr.txt
Run Code Online (Sandbox Code Playgroud)


小智 14

你可能正在寻找这些方面的东西:

    #define OUT_BUFF_SIZE 512

    int main(int argc, char* argv[])
    {
        printf("1: stdout\n");

        StdOutRedirect stdoutRedirect(512);
        stdoutRedirect.Start();
        printf("2: redirected stdout\n");
        stdoutRedirect.Stop();

        printf("3: stdout\n");

        stdoutRedirect.Start();
        printf("4: redirected stdout\n");
        stdoutRedirect.Stop();

        printf("5: stdout\n");

        char szBuffer[OUT_BUFF_SIZE];
        int nOutRead = stdoutRedirect.GetBuffer(szBuffer,OUT_BUFF_SIZE);
        if(nOutRead)
            printf("Redirected outputs: \n%s\n",szBuffer);

        return 0;
    }
Run Code Online (Sandbox Code Playgroud)

这个课将这样做:

#include <windows.h>

#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>

#ifndef _USE_OLD_IOSTREAMS
using namespace std;
#endif

#define READ_FD 0
#define WRITE_FD 1

#define CHECK(a) if ((a)!= 0) return -1;

class StdOutRedirect
{
    public:
        StdOutRedirect(int bufferSize);
        ~StdOutRedirect();

        int Start();
        int Stop();
        int GetBuffer(char *buffer, int size);

    private:
        int fdStdOutPipe[2];
        int fdStdOut;
};

StdOutRedirect::~StdOutRedirect()
{
    _close(fdStdOut);
    _close(fdStdOutPipe[WRITE_FD]);
    _close(fdStdOutPipe[READ_FD]);
}
StdOutRedirect::StdOutRedirect(int bufferSize)
{
    if (_pipe(fdStdOutPipe, bufferSize, O_TEXT)!=0)
    {
        //treat error eventually
    }
    fdStdOut = _dup(_fileno(stdout));
}

int StdOutRedirect::Start()
{
    fflush( stdout );
    CHECK(_dup2(fdStdOutPipe[WRITE_FD], _fileno(stdout)));
    ios::sync_with_stdio();
    setvbuf( stdout, NULL, _IONBF, 0 ); // absolutely needed
    return 0;
}

int StdOutRedirect::Stop()
{
    CHECK(_dup2(fdStdOut, _fileno(stdout)));
    ios::sync_with_stdio();
    return 0;
}

int StdOutRedirect::GetBuffer(char *buffer, int size)
{
    int nOutRead = _read(fdStdOutPipe[READ_FD], buffer, size);
    buffer[nOutRead] = '\0';
    return nOutRead;
}
Run Code Online (Sandbox Code Playgroud)

这是结果:

1: stdout
3: stdout
5: stdout
Redirected outputs:
2: redirected stdout
4: redirected stdout
Run Code Online (Sandbox Code Playgroud)


sho*_*osh 5

使用CreateProcess()创建进程时,可以选择HANDLE要写入stdout和stderr 的进程.这HANDLE可以是您将输出定向到的文件.

这将允许您使用代码而无需重新编译它.只需执行它,而不是使用system()或诸如此类,使用CreateProcess().

您提供的HANDLE CreateProcess()也可以是您创建的管道,然后您可以从管道中读取数据并执行其他操作.