是否有可能以某种方式更改Windows上的标准I / O函数句柄?语言优先是C ++。如果我理解正确,通过选择控制台项目,编译器只需为您预先分配控制台,并操作所有标准I / O函数以使用它的句柄。所以,我想要做的是让一个Console应用程序实际写入另一个应用程序控制台缓冲区。我虽然可以得到第一个控制台句柄,而不是通过文件将其传递给第二个应用程序(我不太了解进程间通信,这看起来很简单)并且以某种方式使用例如第一个应用程序句柄的prinf。可以这样做吗?我知道如何获得控制台句柄,但我不知道如何将printf重定向到该句柄。它只是一个研究目的项目,以更好地了解OS背后的工作。我对printf如何知道它所关联的控制台感兴趣。
答案 0 :(得分:1)
如果我理解正确,听起来您需要Windows API函数AttachConsole(pid)
,它将当前进程附加到PID为pid
的进程所拥有的控制台。
答案 1 :(得分:0)
如果要将printf
重定向到句柄(FILE *),只需执行
fprintf(handle, "...");
例如,使用printf
fprintf
fprintf(stdout, "...");
或错误报告
fprintf(stderr, "FATAL: %s fails", "smurf");
这也是你写文件的方式。 fprintf(file, "Blah.");
答案 2 :(得分:0)
如果我理解你的错误,你可以在http://msdn.microsoft.com/en-us/library/ms682499%28VS.85%29.aspx找到你要写的应用程序的源代码。此示例显示如何在另一个应用程序的stdin
中书写并阅读stdout
。
一般理解。编译器不“为您预先分配控制台”。编译器使用在输出中写入的标准C / C ++库。因此,如果您使用例如printf()
,则最终将执行以下代码:
void Output (PCWSTR pszwText, UINT uTextLenght) // uTextLenght is Lenght in charakters
{
DWORD n;
UINT uCodePage = GetOEMCP(); // CP_OEMCP, CP_THREAD_ACP, CP_ACP
PSTR pszText = _alloca (uTextLenght);
// in the console are typically not used UNICODE, so
if (WideCharToMultiByte (uCodePage, 0, pszwText, uTextLenght,
pszText, uTextLenght, NULL, NULL) != (int)uTextLenght)
return;
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), pszText, uTextLenght, &n, NULL);
//_tprintf (TEXT("%.*ls"), uTextLenght, pszText);
//_puttchar();
//fwrite (pszText, sizeof(TCHAR), uTextLenght, stdout);
//_write (
}
因此,如果更改STD_OUTPUT_HANDLE
的值,则所有输出都将转到文件/管道,依此类推。如果代替WriteFile
程序使用WriteConsole
函数,这样的重定向将不起作用,但标准C / C ++库不会这样做。
如果您希望重定向stdout
不是来自子流程,而是来自当前流程,则可以直接致电SetStdHandle()
(参见http://msdn.microsoft.com/en-us/library/ms686244%28VS.85%29.aspx)。
“分配控制台”做一个操作系统的加载器。它看起来是二进制EXE文件的单词(在IMAGE_OPTIONAL_HEADER
的子系统部分中看到http://msdn.microsoft.com/en-us/library/ms680339%28VS.85%29.aspx),如果EXE在这个地方有{3 {(1}}),那么它使用父进程的控制台处理或创建一个新的。可以在IMAGE_SUBSYSTEM_WINDOWS_CUI
调用的参数中更改此行为(但仅当您在代码中启动子进程时)。您根据链接器开关/子系统定义的EXE的CreateProcess
标志(请参阅http://msdn.microsoft.com/en-us/library/fcc1zstk%28VS.80%29.aspx)。