_WIN32_WINNT 在 header 中更改了定义,这会导致二进制不兼容吗?

_WIN32_WINNT definition changed in header, does this cause a binary incompatibility?

在 VS2010 中,我正在努力将应用程序更新到第三方库的新版本,该第三方库要求 _WIN32_WINNT 至少为 0x501,但另一个提供二进制共享库的第三方共享库定义了它作为应用程序中包含的 header 中的 0x500。

如果这个被修改了,会不会是二进制不兼容或者这是一个无关紧要的变化?我是否必须从将其定义为 0x500 的库中请求新的二进制文件?我不确定如何判断这是否需要新的垃圾箱——我想如果 classes/structs 大小或命名发生变化,或者任何 method/function 签名发生变化,那么就需要进行新的编译。

简短回答:可能不会,但如果是的话,那你就麻烦了。

长答案:

_WIN32_WINNT 控制您的代码将使用的 WinAPI(以及相关库,例如 MFC)的版本。目的是确保如果您使用 Windows 功能,这些功能是在您所针对的 Windows 版本之后引入的。

主要是控制哪些函数、结构等对您可见。除了您未针对的 Windows 版本外,这部分不会导致二进制不兼容。然而...

WinAPI 中有一些结构在 Windows 的生命周期内得到了扩展。例如,看一下 OPENFILENAME:

的定义
typedef struct tagOFN {
  DWORD         lStructSize;
  HWND          hwndOwner;
  HINSTANCE     hInstance;
  LPCTSTR       lpstrFilter;
  LPTSTR        lpstrCustomFilter;
  DWORD         nMaxCustFilter;
  DWORD         nFilterIndex;
  LPTSTR        lpstrFile;
  DWORD         nMaxFile;
  LPTSTR        lpstrFileTitle;
  DWORD         nMaxFileTitle;
  LPCTSTR       lpstrInitialDir;
  LPCTSTR       lpstrTitle;
  DWORD         Flags;
  WORD          nFileOffset;
  WORD          nFileExtension;
  LPCTSTR       lpstrDefExt;
  LPARAM        lCustData;
  LPOFNHOOKPROC lpfnHook;
  LPCTSTR       lpTemplateName;
#if (_WIN32_WINNT >= 0x0500)
  void          *pvReserved;
  DWORD         dwReserved;
  DWORD         FlagsEx;
#endif 
} OPENFILENAME, *LPOPENFILENAME;

看到最后一点了吗?这意味着潜在的麻烦——如果一个代码在 _WIN32_WINNT 设置为 0x400 而另一部分为 0x500 的情况下进行编译,那么您的代码的一部分将假定该结构小于另一部分。

WinAPI的设计者确实考虑过这个问题。您会注意到 OPENFILE 的第一个成员是 lStructSize;你应该用 sizeof(OPENFILE) 初始化它。对你来说,sizeof(OPENFILE) 是一个编译时常量,对于 Windows 运行时库中的函数,它是它们决定你传递给它们的 OPENSTRUCT 结构版本的标签。

在一种情况下这意味着潜在的麻烦:如果二进制库和代码的其余部分交换 WinAPI 类型或指向此类类型的指针,并且如果这些类型在 0x5000x501 之间扩展,然后事情要爆炸了。令人高兴的是,我不希望有很多这样的结构,因为版本范围很窄。但是,如果担心这一点,那么您绝对应该请求新的二进制文件,因为解决它会很困难而且很乏味,而且有很多机会犯错误。

除此之外,我认为你(可能)安全。