zoukankan      html  css  js  c++  java
  • 【转载】标准输入输出重定向(Visual C++)

    原文:标准输入输出重定向(Visual C++)

    引言

        本人偶得在 Visual C++ 中进行输入输出重定向的办法,比通常的做法“freopen”更加的灵活和方便,特在此共享。目前,代码正在不断地摸索和完善中,先把“输出”(stdout)部分提供给大家。

        阅读本文需要有一定的 Visual C++ 开发经验。本文所介绍的内容,只适用于一些特殊需求,不知道“输出重定向”有什么用的朋友,不必感到迷茫。


    1. 简介

        在 Visual C++ 中,有好几种用法与标准输入输出有关:

    系列1:scanf,printf,fprintf(stderr,...)……
    系列2:cin,cout,cerr……
    系列3:GetStdHandle,SetStdHandle……

        使用 MSDN 所介绍“freopen”的方法,能够将以上 3 种输出,都重定向到文件中。但这种用法不是很灵活,如果不是要输出到文件,而是要将输出的内容直接进行处理就不是很方便。

        本人经过摸索,现可以将 <stdio.h> 中的 stdout、stderr;<iostream.h> 中的 cout、cerr、clog;<winbase.h> 中的 STD_OUTPUT_HANDLE、STD_ERROR_HANDLE 各自重定向到不同的地方,并且还支持一种特殊的重定向:重定向到回调函数(Callback Function),特在此共享。


    2. 功能讲解

        本次提供的功能,方法名叫做 RedirectStdout,传递给它的参数主要有 4 个:

    1. 哪些输出要被重定向。比如:指定 (stderr | cout) ,那么其他的输出仍然输出到屏幕。
    2. 重定向到哪里。比如:重定向到文件,还是到屏幕,还是到回调函数。
    3. 文件名。如果是重定向到文件,则需要指定文件名。
    4. 回调函数。如果是重定向要回调函数,则需要指定回调函数。

        接口头文件:

    // 可能的输出,用在第一个参数(可组合使用)
    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>
    };

    // 重定向的目标,用于第二个参数(不可组合使用,一次只能使用一个)
    enum RedirectTypes
    {
        REDIR_TO_NUL     , // 重定向到空,什么都不显示
        REDIR_TO_CON     , // 重定向回到屏幕
        REDIR_TO_PRN     , // 重定向到打印机(本人没有测试过)
        REDIR_TO_FILE    , // 重定向到文件,第三个参数指定文件名
        REDIR_TO_CALLBACK, // 重定向到回调函数,第三个参数指定回调函数
    };

    // 回调函数形式
    typedef VOID (*LPREDIRECT_CALLBACK)(LPCSTR, INT nDataSize, DWORD);

    // 两种调用格式,到文件或者到回调。第四个参数指定是否 Append 或附加信息 DWORD
    // 如果是其他的,第三个参数可省。
    BOOL RedirectStdout(INT, RedirectTypes, LPCSTR lpszFileName, BOOL);
    BOOL RedirectStdout(INT, RedirectTypes, LPREDIRECT_CALLBACK, DWORD);

    3. 使用方法

    3.1 头文件

        本次提供下载的包中,包含 2 个头文件:"stdredir.h" 和 "stdredirdll.h"。使用第一个头文件将静态连接 "STDRedirStatic.lib",使用第二个头文件动态连接 "STDRedirDll.dll"。

        使用时只能包含其中一个头文件,不能将两个同时包含。

    3.2 项目设置

        本次提供的静态和动态库,均使用 "Multithreaded DLL",DEBUG 版使用 "Debug Multithreaded DLL"。当在控制台运行时需要注意添加 MFC 支持。


    4. 下载

    [out_redir.zip] - 25kb


    5. 举例

    5.1 使用下列步骤创建:
    1. 创建一个 "Dialog based" 项目。
       
    2. 在 Dialog 类中,添加静态方法:
      static VOID PrintfCallback(LPCSTR szData, INT nDataSize, DWORD dwData);
       
    3. 在 Dialog 中,添加一个 CEdit 框和一个按钮。
       
    4. 在 OnInitDialog() 中,添加重定向代码:
      RedirectStdout(OUT_STDOUT, REDIR_TO_CALLBACK, PrintfCallback, (DWORD)this);
       
    5. 在按钮的事件中添加 printf 操作:
      printf("test ");
       
    6. 在回调函数中,对 printf 的内容在 CEdit 中显示:
      CTDlgTestDlg * pDlg = (CTDlgTestDlg*)dwData;

      pDlg->m_edtShow.SetSel(
              pDlg->m_edtShow.GetWindowTextLength(),
              pDlg->m_edtShow.GetWindowTextLength()
      );
      pDlg->m_edtShow.ReplaceSel(szData);
    5.2 示例下载:

    [example.zip] - 15kb(需要前面的 out_redir.zip 才能编译连接)

    5.3 示例截图


    (代码截图)


    (运行时截图)

  • 相关阅读:
    weblogic复现利用系列-2019
    weblogic复现利用系列-2020
    Python3编码解码与数据类型转换
    weblogic复现利用系列-2017
    weblogic从ssrf到redis获取shell
    fastjson反序列化复现
    shiro721复现
    Shiro550复现和挖掘思路
    RMI反序列化
    手写一个admin 组件------STARK
  • 原文地址:https://www.cnblogs.com/zhehan54/p/5891775.html
Copyright © 2011-2022 走看看