【问题标题】:timeval undefined when using windows.h and WIN32_LEAN_AND_MEAN使用 windows.h 和 WIN32_LEAN_AND_MEAN 时未定义时间
【发布时间】:2009-12-15 18:18:17
【问题描述】:

为了避免与 winsock2.h 冲突,我想用 WIN32_LEAN_AND_MEAN 包装我的 windows.h 包含(我在 windows.h 之后取消它,以免干扰包含我的标头的应用程序)。当 winsock2.h 不包括在内时,这样做会导致 timeval 未定义。包括 time.h 也没有定义 timeval。

我如何才能定义 timeval (a) 无需包含 winsock2.h,(b) 不要求包含我的标头的应用程序在我的标头之前包含 winsock2.h,(c) 允许应用程序包含 winsock2.h,如果他们需要它们,并且 (d) 不必自己定义 timeval,因为它可能已经由父应用程序包含的标头定义?

【问题讨论】:

  • 你不能在包含 windows.h 之后简单地取消它,因为你已经改变了以后重新包含它的行为(考虑包含警卫或 pragma 一次)。理想情况下,WIN32_LEAN_AND_MEAN(和其他此类“标头配置”宏)应该是项目范围的设置;但除此之外,您仍然必须在整个翻译单元中始终如一地使用它们。 (反例:标准 NDEBUG 宏被定义为允许更改,因此 assert.h/cassert 的行为与其他头文件非常不同,并且经常造成混淆​​。许多项目因此避免使用它并使用自定义 DEBUG 宏。)跨度>

标签: c++ windows winsock timeval


【解决方案1】:

请记住,WIN32_LEAN_AND_MEAN 是编译器性能优化。使用它可以让你的应用程序编译得更快一些,但代价是省略了一些 Windows API 中使用较少的部分。

您可以使用一种更精细的禁用(NOIMM 等),但与 LEAN_AND_MEAN 相比,这些对编译时间的影响甚至更小。

除非您的项目非常大并且编译时间长而繁重,否则我会停止使用 WIN32_LEAN_AND_MEAN。

马丁

【讨论】:

  • 我认为问题在于他想使用winsock2,但winsock中的定义(由windows.h引入)冲突。 PS:写这个评论感觉很元:)
【解决方案2】:

我没有定义任何一个 LEAN_AND_MEAN,而是在包含 windows.h 之前明确地为每个“NO”执行以下操作

//  Exclude Input Method Manager (International stuff...one day)
#if !defined    NOIMM
    #define NOIME
    #define NOIMM
#endif

//  Exclude Metafile API
#if !defined    NOMETAFILE
    #define NOMETAFILE
#endif

这允许我使用相同的 StdAfx.h。使用 VS2010,我可以在 windows.h 之后包含 Winsock2 而不会发生冲突。

Stdafx 稍长一些,但清楚地记录了包含和排除的内容。

【讨论】:

    【解决方案3】:

    这就是我处理 winsock2.h 问题的方式(假设是 Visual C++):

    • 我将构建系统配置为始终在命令行上将/D_WINSOCKAPI_ 传递给编译器,这样就不会隐式包含任何winsock 头文件。
    • 当我想包含 winsock2.h 时,我会通过代理头文件来执行此操作,该代理头文件为我做了一些预处理程序。

    这就是我的头文件的工作方式:

    #pragma push_macro("_WINSOCKAPI_")
    #undef _WINSOCKAPI_
    #include <winsock2.h> 
    #pragma pop_macro("_WINSOCKAPI_")
    

    如果你这样做,那么你就不需要#define WIN32_LEAN_AND_MEAN,你可以只在需要时使用winsock2.h

    【讨论】:

      【解决方案4】:

      我不认为你想要什么是可能的。 timeval 结构在 winsock.h 和 winsock2.h 中定义,因此您必须包含其中之一才能获得定义。如果不定义 WIN32_LEAN_AND_MEAN,windows.h 将包含 winsock.h;这使得无法包含winsock2.h。如果您定义 WIN32_LEAN_AND_MEAN,则不会自动包含两个 winsock 头文件,因此您不会获得 timeval 的定义。我认为您最好的选择是要求应用程序明确包含一个 winsock 标头。

      【讨论】:

      • 看我的回答:如果你按照我的方式配置你的构建系统,那绝对是可能的。
      猜你喜欢
      • 2021-02-27
      • 2017-09-25
      • 2017-10-10
      • 2018-07-08
      • 1970-01-01
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多