将 STD_OUTPUT_HANDLE 作为输入 HANDLE 直接传递给 WriteFile 是否合法?

is it legal to pass STD_OUTPUT_HANDLE directly as input HANDLE to WriteFile?

WinApi WriteFile() 函数似乎直接接受 STD_xxx_HANDLE 常量作为第一个参数。我执行了以下命令:

#include <windows.h>
main() {
    DWORD bw;

    WriteFile( (void *)STD_OUTPUT_HANDLE,       "output", 6, &bw, NULL);
    WriteFile( GetStdHandle(STD_OUTPUT_HANDLE), "output", 6, &bw, NULL);

    WriteFile( (void *)STD_ERROR_HANDLE,        "error", 5, &bw, NULL);
    WriteFile( GetStdHandle(STD_ERROR_HANDLE),  "error", 6, &bw, NULL);
}

以上示例将 "output" 两次写入 stdout,将 "error" 两次写入 stderr。我已经在 Win XP 和 Win 7 上测试过(我无法访问 WINE 或 Win 10)。

我可以看到 GetStdHandle() 确实转换了值(在 STD_OUTPUT_HANDLE 的情况下从 -11 到 7),但是任何一个值都与 WriteFile() 输入相同 HANDLE.

当 WriteFile 将 STD_xxx_HANDLE 常量识别为其 HANDLE 输入时,它是否隐含地执行 GetStdHandle()?我看过但找不到这个记录。

是的,我知道如果没有记录,请不要这样做...我只是想知道我是否遗漏了什么。

WriteFile expects a handle. The STD_xxx_HANDLE values are not handles. It is not legal to pass those values to WriteFile. You have to convert them to handles by calling GetStdHandle.

令人惊讶的是,这甚至适用于 Windows 95 RTM 和 NT 4(以及 XP 和 8)所以它似乎是故意的。我不能告诉你为什么,也不能告诉你这在 NT 3.x 有多远。

但它没有记录,也不是 ABI 的真正组成部分,所以我建议您继续调用 GetStdHandle 以避免将来出现令人讨厌的意外。