_WIN32_WINNT标头中的定义更改,这是否会导致二进制不兼容

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

本文关键字:是否 不兼容 二进制 WINNT WIN32 定义      更新时间:2023-10-16

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

如果对此进行了修改,是否存在二进制不兼容或这是一个微不足道的更改?我是否必须从将其定义为0x500的库中请求新的二进制文件?我不确定如何判断这是否需要新的 bin——我认为如果任何类/结构的大小或命名发生变化,或者任何方法/函数签名发生变化,那么就需要一个新的编译。

简短的回答:可能不是,但如果确实如此,你就陷入了困境。

长答案:

_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 之间扩展,那么事情就会爆炸。令人高兴的是,我不希望有很多这样的结构,因为版本范围非常窄。但是,如果这是一个担忧,那么您绝对应该请求新的二进制文件,因为解决它将是困难和乏味的,有很多犯错误的机会。

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