Stdio Redirect(Visual C++)
[All rights reserved: http://www.regexlab.com/stdredir/]
Preface
I have gotten a way to redirect stdio in Visual C++, which is more convenient than "freopen", so I share it to everyone. Now, the code is under completing, I will share the "stdout" redirect first.
Some experiences in Visual C++ are needed to read this article. The content in this article is useful at certain situations, so those friends, who don't know what is stdio-redirect, need not to be puzzled.
1. Introduction
In Visual C++, there are several groups of methods about stdio:
Group 1: scanf, printf, fprintf(stderr,...)......
Group 2: cin, cout, cerr......
Group 3: GetStdHandle, SetStdHandle......
Use the method "freopen", we can redirect those 3 types of output to file. But, if we don't need redirect to file, but need to use the output data directly, "freopen" is not convenient.
Now, we could redirect each of them separately: stdout, stderr in <stdio.h>; cout, cerr, clog in<iostream.h>; STD_OUTPUT_HANDLE, STD_ERROR_HANDLE in <winbase.h>. Each of then can be redirected to a different destination. And, a special type of
destination can be supported: redirect to a callback function.
2. Function
The newly provided method is RedirectStdout. There are 4 parameters needed:
- Which outputs to be redirected. Such as (stderr | cout).
- Where to redirect. Such as: to file, to console or callback.
- File name. If redirect to file, this parameter is needed.
- Callback function. If redirect to callback, this parameter is needed.
Header file:
// outputs, used as 1st parameter
enum OutTypes
{
OUT_STDOUT = 0x0001, // stdout <stdio.h>
OUT_STDERR = 0x0002, // stderr <stdio.h>
OUT_COUT = 0x0004, // cout <iostream.h>
OUT_CERR = 0x0008, // cerr <iostream.h>
OUT_CLOG = 0x0010, // clog <iostream.h>
OUT_OUTPUT_HANDLE = 0x0020, // STD_OUTPUT_HANDLE <winbase.h>
OUT_ERROR_HANDLE = 0x0040, // STD_ERROR_HANDLE <winbase.h>
};
// redirect destiation, used as 2nd parameter
enum RedirectTypes
{
REDIR_TO_NUL , // to null, nothing will be shown or saved
REDIR_TO_CON , // back to console
REDIR_TO_PRN , // to printer (never tested)
REDIR_TO_FILE , // to file
REDIR_TO_CALLBACK, // to callback
};
// Callback function
typedef
VOID (*LPREDIRECT_CALLBACK)(LPCSTR, INT nDataSize, DWORD);
// Two forms for file and callback, the 4th is 'Append'or data
// The 3rd can be omitted if redirect to NUL/CON/PRN
BOOL RedirectStdout(INT, RedirectTypes, LPCSTR lpszFileName, BOOL);
BOOL RedirectStdout(INT, RedirectTypes, LPREDIRECT_CALLBACK, DWORD); |
3. How to use
3.1 Header file
There are two header file in the downloaded package: "stdredir.h" and "stdredirdll.h". If the first, "STDRedirStatic.lib" will be linked staticly. If the second, "STDRedirDll.dll" will be linked dynamicly.
Only one header file can be used in one project.
3.2 Project settings
Runtime library "Multithreaded DLL" is used. "Debug Multithreaded DLL" is used by DEBUG version.
4. Download
[out_redir.zip] - 25kb
5. Example
5.1 Please use the following steps:
- Create a "Dialog based" project.
- In the main Dialog class, add a static method as the callback:
static VOID PrintfCallback(LPCSTR szData, INT nDataSize, DWORD dwData);
- In the Dialog, add a CEdit box and a button.
- In OnInitDialog() , add the redirect code:
RedirectStdout(OUT_STDOUT, REDIR_TO_CALLBACK, PrintfCallback, (DWORD)this);
- In the event handler of the button, add a printf:
printf("test\n");
- In the callback, show the data printed by 'printf' to Edit box:
CTDlgTestDlg * pDlg = (CTDlgTestDlg*)dwData;
pDlg->m_edtShow.SetSel( pDlg->m_edtShow.GetWindowTextLength(),
pDlg->m_edtShow.GetWindowTextLength() ); pDlg->m_edtShow.ReplaceSel(szData);
5.2 Example download:
[example.zip] - 15kb (out_redir.zip is need to build this demo)
5.3 Example snapshot
(Code snapshot)
(Runtime snapshot)
6. Relative Sponsored Links
|