2

(这个问题以 zlib 为例,但并不具体。)

我正在尝试使用它附带的 MSVC 项目文件在 Windows 上编译 zlib。我正在使用带有 Windows 8 SDK 的 VS2012,但我的构建机器是 Windows 7。

Zlib 包含以下代码:

#ifdef IOWIN32_USING_WINRT_API
    if ((filename!=NULL) && (dwDesiredAccess != 0))
        hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
#else
    if ((filename!=NULL) && (dwDesiredAccess != 0))
        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
#endif

其中 IOWIN32_USING_WINRT_API 设置如下

#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#define IOWIN32_USING_WINRT_API 1
#endif
#endif

WINAPI_FAMILY_PARTITION 和 WINAPI_PARTITION_APP 是在 Windows 8 SDK (winapifamily.h) 中定义的,所以结果是 zlib 中使用 CreateFile2 的代码可以编译。

我可以编译 zlib,但任何尝试加载它的应用程序都会失败,因为它找不到 CreateFile2,这是正确的,因为我的机器是 Windows 7,并且该 API 是在 Windows 8 中引入的。

这是我第一次在低于其支持的 Windows 版本上使用 Windows SDK,因此我的问题是:

我唯一的办法是修补 zlib 以在第一行添加对 _WIN32_WINNT >= _WIN32_WINNT_WIN8 的检查,并将 /D_WIN32_WINNT=_WIN32_WINNT_WIN7 传递给 msbuild?这意味着我必须构建两组二进制文件——一组支持 Win7(通过传递 /D),另一组支持 Win8(不传递 /D)。

如果在 Windows 8 上运行,有没有办法让一个通用的二进制文件在 Windows 7 和 8 上运行并使用 CreateFile2 代码路径?(我想那是 GetProcAddress + 函数指针。还有什么?)

4

4 回答 4

4

这个问题很老,但如果有人仍然有这个问题,我只是通过修改(iowin32.c 文件第 28 行)中的代码,成功地使用 msvc 12.0 针对 Windows 7 构建了最新的 zlib,如下所示:

#if _WIN32_WINNT >= _WIN32_WINNT_WIN8
#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#define IOWIN32_USING_WINRT_API 1
#endif
#endif
#endif

当然,要完成这项工作,您需要在以下位置定义一个宏:配置属性 > C/C++ > 预处理器:

_WIN32_WINNT=0x0601

这意味着您的目标是 Windows 7(如果使用 Windows 7 SDK,则不需要)

然后成功重建项目:) 是的,当然,此修复仅适用于您使用的 Windows 早于 Windows 8。

但是,这不是 zlib 的唯一错误,您肯定会在 zlib.def 文件中遇到不匹配的版本。要解决此问题,请打开包含错误的 zlib.def 文件并将1.2.8替换为1.28 或任何版本

于 2014-08-12T07:39:09.220 回答
4

您可以使用_WIN32_WINNT来选择要定位的操作系统版本。这是损坏的 zlib 检查。WINAPI_FAMILY_DESKTOP_APP包括WINAPI_FAMILY_APP所以他们的检查总是成功的。您可以像这样修复它:

#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
#if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY_DESKTOP_APP, WINAPI_PARTITION_APP)
#define IOWIN32_USING_WINRT_API 1
#endif
#endif

请参阅此处了解更多信息:http ://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/3965645c-978c-4148-b32c-1853f7fd22b3

于 2013-06-14T16:26:51.473 回答
2

您可以这样做,因为您至少为 VS2012 安装了 Update 1,因为这使您能够为 XP 进行编译,它链接到 Windows 7 SDK 的缩减版本。

我们使用我们的一些代码来做到这一点,它与 XP、Windows 7 和 Windows 8 兼容。

有关详细信息,请参阅此处的 MSDN 博客

下面的关键信息

微软

于 2013-06-14T10:33:32.140 回答
0

据我所知,唯一的方法是使用LoadLibrary()-GetProcAddress()你也可以在处理 WIn7(或更高版本)原生消息的 MFC Sources 中看到这一点

例如:CWnd::OnGesture()%VCINSTALLDIR%atlmfc\src\mfc\wincore.cpp

于 2013-06-14T08:11:04.863 回答