羽毛球

生活在别处

导航

<2005年6月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

统计

留言簿(29)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜

标准输出(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”即可。

posted on 2005-06-06 18:28 Michael 阅读(4041) 评论(4)  编辑 收藏

评论

# re: 标准输出(stdout)重定向 2005-06-06 19:01 Michael

内容怎么显示不出来?

# re: 标准输出(stdout)重定向 2005-06-06 19:03 Michael

浏览器用Firefox,提交内容好几次,这里都显示不出来?
用IE登陆blog,不提示密码错误,但还是显示登陆界面,进去不了。

哪位仁兄知道怎么回事?

# re: 标准输出(stdout)重定向 2005-06-06 19:38 Michael

找到原因:我IE中禁用了所有Cookie。

# re: 标准输出(stdout)重定向 2006-04-08 10:26 新一代爆头专家

终于找到一个可用的example, 非常感谢, 加上两个include就更完美了....
#include  <io.h>
#include <FCNTL.h>

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]