首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >stderr的文件描述符不等于2

stderr的文件描述符不等于2
EN

Stack Overflow用户
提问于 2021-01-27 23:53:34
回答 1查看 124关注 0票数 1

我一直在开发一个Windows GUI应用程序,这意味着在默认情况下,它不会获得标准的输入/输出/错误处理。此GUI应用程序也是另一个GUI应用程序的子进程(渲染到嵌入式窗口中,标准句柄用于统一日志记录)。我们在现有代码中有一个断言,它被重用于子进程,其条件是_fileno(stderr) == 2。当根本没有标准句柄时,这个断言当然已经失败了,正如微软文档中所说的那样,返回-2。为了需要这些标准句柄,我调用了AllocConsole()函数来生成它们,然后再进入这段代码。但是,对于AllocConsole(),断言仍然失败,因为_fileno(stderr)返回4,而_fileno(stdout)似乎返回3。

我的理解是,文件描述符是按创建顺序编号的,从0开始。至少这是针对相同函数的POSIX文档,而不是针对WIN32的。至少,看起来WIN32函数并不符合POSIX。这本身并不令人惊讶。但我在微软文档中也看不到任何东西来解释这种行为偏差。因此,如果最初没有标准句柄,为什么生成它们不会给它们提供预期的编号,0 (stdin) 1 (stdout) 2 (stderr)?如果新文件的编号在标准文件之后开始,那么我们不应该期待_fileno(stderr) == 5而不是4,因为_fileno(stdin)将是3而不是_fileno(stdout) == 3吗?

仅供参考,我不是在这里找工作。我已经用wmain替换了wWinMain,并将子进程的项目更改为控制台应用程序。通过这种方式,一切都能按预期运行。我只是在寻找一个解释,为什么文件编号看起来如此错误。

EN

回答 1

Stack Overflow用户

发布于 2021-01-28 14:57:55

所以,如果最初没有标准句柄,为什么生成它们不会给它们提供预期的编号,0(

)1 (stdout) 2 (stderr)?

根据AllocConsole的说法

AllocConsole为新控制台初始化标准输入、标准输出和标准错误句柄。标准输入句柄是控制台输入缓冲区的句柄,标准输出和标准错误句柄是控制台屏幕缓冲区的句柄。要检索这些句柄,请使用GetStdHandle函数。

所以在AllocConsole之后有标准的句柄。_fileno返回-2的原因只是"__stdout or stderr不与输出流相关联“。

如果新文件的编号在标准文件之后开始,那么我们不应该期待_fileno(stderr) == 5而不是4,因为_fileno(stdin)将是3而不是_fileno(stdout) == 3吗?

freopen会生成一个新的fd,即从3开始,_fileno(stderr) =4的原因可能是您没有重新打开stdin。所有3个都要重新打开:

代码语言:javascript
复制
if (AllocConsole()) {
    freopen("CONIN$", "r", stdin);
    freopen("CONOUT$", "w", stdout);
    freopen("CONOUT$", "w", stderr);
}

我会像预期的那样得到3,4,5。

建议直接使用GetStdHandle返回的句柄,而不使用文件描述符。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65922679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档