Chinaunix首页 | 论坛 | 博客
  • 博客访问: 367935
  • 博文数量: 715
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:46
文章分类

全部博文(715)

文章存档

2011年(1)

2008年(714)

我的朋友

分类:

2008-10-13 16:29:58

公司有个同事用了一个很老的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 阅读(3768)   


--------------------next---------------------

阅读(574) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~