你目前正处于脱机状态,正在等待 Internet 重新连接

信息: 从 GUI 应用程序中调用 CRT 输出例程

注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。

点击这里察看该文章的英文版: 105305
概要
若要使用如 printf 从一个 GUI 应用程序 () 的 C 运行时输出例程就需要创建的控制台。Win32 应用程序编程接口 (API) AllocConsole() 创建控制台。CRT 例行 setvbuf() 删除缓冲以便输出将立即可见。

如果从命令行或从文件管理器运行 GUI 应用程序时,此方法有效。但是,此方法不起作用如果从程序管理器或通过"启动"命令启动应用程序。下面的代码演示如何解决此问题:
   int hCrt;   FILE *hf;   AllocConsole();   hCrt = _open_osfhandle(             (long) GetStdHandle(STD_OUTPUT_HANDLE),             _O_TEXT          );   hf = _fdopen( hCrt, "w" );   *stdout = *hf;   i = setvbuf( stdout, NULL, _IONBF, 0 );				
此代码打开最新的低级别的 CRT 手柄以正确的控制台输出句柄,将新的流与该低级句柄相关联并使用该新流替换标准输出。此进程负责使用如 printf ()、 puts(),等的标准输出的函数。stdin 和 stderr 使用相同的过程。

请注意此代码不能更正问题的句柄 0、 1 和 2。实际上,到其他的复杂性由于不可能要更正此,并且因此有必要使用 I/O 流,而不是低级的 I/O。
更多信息
在 GUI 应用程序启动时与在"启动"三个标准操作系统的命令处理 STD_INPUT_HANDLE、 STD_OUTPUT_HANDLE 和 STD_ERROR_HANDLE 全部"出归零"的控制台的初始化例程。在 GUI 应用程序调用 AllocConsole() 时,这些三个句柄会替换为有效的值。因此,一旦这样做是调用 GetStdHandle() 将总是返回有效的句柄值。问题在于 CRT 已经完成初始化之前您的应用程序获取调用 AllocConsole() 机会 ; 三个低 I/O 手柄 0 和 1,2 已经被安装了使用原始归零出操作系统手柄,因此所有的 CRT i/o 操作发送到无效的操作系统句柄和 CRT 输出未出现在 $ 控制台中。使用上文所述来消除此问题的解决方法。

从"启动"命令不带命令行启动 GUI 应用程序的情况下标准操作系统句柄不正确零出,但错误地继承 CMD.EXE。当应用程序的 CRT 初始化时,三个低 I/O 手柄 0 和 1,2 都初始化为使用三个句柄号 CMD.EXE 从继承的应用程序。当应用程序调用 AllocConsole() 时, 控制台的初始化例程尝试替换控制台初始化的认为是无效的标准操作系统句柄值与新的控制台中的有效的句柄值。通过巧合,因为控制台的初始化例程往往会透露相同的三个值的标准操作系统句柄控制台 initilization 将替换标准操作系统句柄值具有相同的值都有--从 CMD.EXE 继承该文件之前。因此,CRT I/O 在这种情况下工作。

值得实现能够使用 CRT 例程中从命令行运行在 GUI 应用程序不是设计使然,这可能不起作用在未来版本的 Windows NT 或 Windows。在将来的版本中您可能需要解决方法,而不只是为使用"开始 < 应用程序名称 >"启动命令行上的应用程序,而且还在命令行中使用"应用程序名称"上启动的应用程序。
3.10 3.50 CRT 重定向 std 控点

Warning: This article has been translated automatically

属性

文章 ID:105305 - 上次审阅时间:11/21/2006 15:41:01 - 修订版本: 4.2

Microsoft Win32 Application Programming Interface

  • kbmt kbconsole kbinfo kbkernbase KB105305 KbMtzh
反馈