分享

VC知识库BLOG

 oskycar 2011-09-22

标准输出(stdout)重定向

公司有个同事用了一个很老的DLL,其信息都是输出到控制台窗口(console),问能不能将其输出到MFC的view中?

我们知道,标准输出默认情况下是输出到console中。
要将stdout重定向到文件, 比较简单,code如下(MSDN中源码):

//将stdout重定向到文件中
   FILE *stream ;
   
if((stream = freopen("file.txt""w", stdout)) == NULL)
      exit(
-1);
   printf(
"this is stdout output ");

   
//重新将stdout重定向到console
   stream = freopen("CON""w", stdout);
   printf(
"And now back to the console once again ");


但是将stdout重定向某个MFC程序View中显示出来,实现稍有点复杂。总体思路是
  1)创建一个匿名管道(pipe)
  2)将stdout重定向到这个pipe上
  3)创建一个线程,读取pipe中的内容,然后将这些内容输出到你希望输出的地方,譬如一个view里。
启动进程时,先调用StdoutRedirect(),那么这个进程中所有的printf都可以输出到View里。

code如下:

HANDLE hOutputReadTmp = 0;
HANDLE hOutputWrite 
= 0;
void DisplayError(char* szMsg)
{
    TRACE(szMsg);
    TRACE(
" ");
}


DWORD WINAPI ReadStdout(LPVOID lpvThreadParam)
{
  CHAR lpBuffer[
256];
  DWORD nBytesRead;

  
while(TRUE)
  
{         
     
if (!ReadFile(hOutputReadTmp, lpBuffer,sizeof(lpBuffer),
                                      
&nBytesRead,NULL) || !nBytesRead)
     
{
        
if (GetLastError() == ERROR_BROKEN_PIPE)
           
break// pipe done - normal exit path.
        else
           DisplayError(
"ReadFile"); // Something bad happened.
     }

    
     
if (nBytesRead >0 )
     
{
         
//获取到printf的输出
         lpBuffer[nBytesRead] = 0;
     
        
//replace your code here. Do it yourself.
        DisplayInView(lpBuffer); 
     }

  }


  
return 0;
}


void StdoutRedirect()
{
    
if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,0,0))
         DisplayError(
"CreatePipe");

   
int hCrt;
   FILE 
*hf;
   
//AllocConsole();
   hCrt = _open_osfhandle(
             (
long)hOutputWrite,
             _O_TEXT
          );
   hf 
= _fdopen( hCrt, "w" );
   
*stdout = *hf;
   
int i = setvbuf( stdout, NULL, _IONBF, 0 );

      
// Launch the thread that gets the input and sends it to the child.
    DWORD ThreadID;
    HANDLE hThread 
= ::CreateThread(NULL,0,ReadStdout,
                              
0,0,&ThreadID);
}


最后,顺便提一下,如果要redirect某个console进程的stdout,也是类似。MSDN有详细例子。搜索“stdout redirect”即可。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多