资源简介
可利用本方法在没有源码的情况下,将console程序的标准输出重定向到自己的程序中来。网上很多关于此类方法的描述,经实验大多在标准Unix和Linux上可用,有个别在VC2010通过匿名管道方式可用,但在VS2015的CRT运行时库下失效,主要是*stdout = *hf;语句失效导致,本代码重新通过命名管道方式得以通用实现,在VS2010、VS2015下均能得到正确结果。
代码片段和文件信息
#include “stdio.h“
#include “windows.h“
#include “io.h“
#include
#include
#define _O_TEXT 0x4000 /* file mode is text (translated) */
#define BUF_SIZE (4096)
HANDLE m_hOutputReadTmp = INVALID_HANDLE_VALUE;
// HANDLE m_hOutputWrite = INVALID_HANDLE_VALUE;
void DisplayMsg(char* szMsg)
{
OutputDebugStringA(szMsg);
}
//callback function of stdout redirect:
void RedirectStdOutCallback(char* buf unsigned int bytes)
{ //the data is redirected into the buf[].
DisplayMsg(buf);
}
DWORD WINAPI ReadStdoutThread(LPVOID lpvThreadParam)
{
HANDLE hStdRead = m_hOutputReadTmp;
char lpBuffer[BUF_SIZE];
DWORD nBytesRead=0;
while (TRUE){
if (!ReadFile(hStdRead lpBuffer sizeof(lpBuffer)-1 &nBytesRead NULL)|| !nBytesRead){
DWORD result = GetLastError();
if (result == ERROR_IO_PENDING){
Yield();
continue;
}
// if (result == ERROR_HANDLE_EOF || result == ERROR_BROKEN_PIPE)
// break;
DisplayMsg(“std redirect reading failed.“);//Something bad happened.
break;
}
if(nBytesRead <= 3){
// Windows has a habit of sending 1 or 2 characters of every message and then sending
// the rest in a second message. This is “ok“ really except our Console class is hardly
// free of overhead so it‘s helpful if we can concatenate the couple of messages together.
// But we don‘t want to break the ability to print progressive status bars like ‘....‘
// so I use a clever Yield/Peek loop combo that keeps reading as long as there‘s new data
// immediately being fed to our pipe.
DWORD u32_avail = 0;
do{
Yield();
if (!PeekNamedPipe(hStdRead 0 0 0 &u32_avail 0))
break;
if (u32_avail == 0)
break;
DWORD loopread=0;
if (!ReadFile(hStdRead &lpBuffer[nBytesRead] sizeof(lpBuffer) - nBytesRead - 1 &loopread NULL)|| !loopread)
break;
nBytesRead+=loopread;
}while(nBytesRead }
//get the output of printf function:
lpBuffer[nBytesRead] = ‘\0‘;
//replace your code here. Do it yourself.
RedirectStdOutCallback(lpBuffer nBytesRead);
}
return 0;
}
bool StdoutRedirect(FILE* stdstream)
{
bool bRet = false;
if (!stdstream)
return bRet;
FILE *hf = NULL;
do {
// if (!CreatePipe(&m_hOutputReadTmp &m_hOutputWrite 0 0)){
// DisplayMsg(“CreatePipe“);
// break;
// }
const char * stream_name = (stdstream == stderr ? “stderr“ : “stdout“);
char pipe_name[128] = { ‘\0‘ };
sprintf(pipe_name “\\\\.\\pipe\\stdredirect_%s%d“ stream_name GetCurrentProcessId());
m_hOutputReadTmp = CreateNamedPipe(pipe_name PIPE_ACCESS_INBOUND 0 1 BUF_SIZE BUF_SIZE 0 NULL);
if (m_hOutputReadTmp == INVALID_HANDLE_VALUE)
break;
// int hCrt;
hf = freopen(pipe_name “wb“ stdstream);
// //AllocConsole();
// hCrt = _open_osfhandle((long)m_hOutpu
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 888 2018-09-07 21:48 stdredirect.sln
文件 4375 2018-09-08 13:59 stdredirect.vcxproj
文件 506 2018-09-07 21:48 stdredirect.vcxproj.filters
文件 143 2018-09-07 20:18 stdredirect.vcxproj.user
文件 2559 2018-09-07 21:46 标准输出(stdout)重定向.txt
文件 3822 2018-09-08 14:31 stdredirect.cpp
- 上一篇:三维模型布尔运算 求并、交、差
- 下一篇:Ecshop礼品卡和储值卡插件
评论
共有 条评论