jww*_*jww 1 windows platform visual-studio windows-7 visual-studio-2012
我正在使用 Visual Studio 2012 在 Windows 7 x64 上执行一些测试。看来 Microsoft 的工具链设置_WIN32_WINNT为0x602( _WIN32_WINNT_WIN8)。运行我们的测试程序结果The procedure entry point GetOverlappedResultEx could not be located in the dynamic link library KERNEL32.dll:
我有两个问题。首先,出于病态的好奇心,为什么 Microsoft 设置_WIN32_WINNT的值对执行环境无效?我可以理解用户是否想要这样做,但不能理解 Microsoft,因为它破坏了事物(qv)。
第二,我们如何设置WINVER或_WIN32_WINNT到象征性的“本平台”?在这种情况下,“这个平台”是 Windows 7。当我在 Windows Vista 上测试时,它将是一个不同的平台。当我在 Windows 8 上测试时,它将是另一个平台。当我在 Windows Phone 和 Windows Store 的 ARM 开发人员提示下进行测试时,它将是另一个平台。
这个问题很容易复制。以下是步骤。我想任何拥有良好测试环境的人都已经完成了前八个步骤。
然后:
hello_world.cpp(这应该留下 1 个解决方案文件、1 个项目文件、1 个源文件)我可以发布 MCVE,这是一个空的源文件,以安抚一些人。这似乎是在浪费时间,因为问题在于工具链而不是源文件。空main对这个问题真的很重要吗?无论文件中的内容如何,都将设置错误WINVER和_WIN32_WINNT。
我知道错误的根源。我们最近更改了代码,以更好地支持Windows 8、Phone 8、Store 8、Server 2012、Windows 10、Phone 10、Store 10 和 Windows Universal Platform。更改如下所示:
#if defined(CRYPTOPP_WIN32_AVAILABLE)
# if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/))
# include <synchapi.h>
# include <ioapiset.h>
# define USE_WINDOWS8_API
# endif
#endif
...
#if defined(USE_WINDOWS8_API)
BOOL result = GetOverlappedResultEx(GetHandle(), &m_overlapped, &m_lastResult, INFINITE, FALSE);
#else
BOOL result = GetOverlappedResult(GetHandle(), &m_overlapped, &m_lastResult, FALSE);
#endif
Run Code Online (Sandbox Code Playgroud)
具有讽刺意味的是,我们首先添加USE_WINDOWS8_API了额外的包含和调用GetOverlappedResultEx来安抚工具。他们抱怨不推荐使用的函数并导致脏编译。脏编译给用户带来了治理、C&A 和 ST&E 问题。
我审核了代码以确保我们不会无意或错误地设置值。我验证了我们在一个地方执行此操作,并且代码路径未激活,因为 Microsoft 的工具链将值设置为0x602:
#ifdef CRYPTOPP_WIN32_AVAILABLE
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
# endif
#endif
Run Code Online (Sandbox Code Playgroud)
这是一个相关的堆栈溢出问题:什么是 WINVER?,但没有讨论如何将其设置为“此平台”。
这是微软关于这个主题的文档:Using the Windows Headers and Modifying WINVER and _WIN32_WINNT。具有讽刺意味的是,他们并没有真正讨论问题或 Windows 10、Windows Phone 10、Windows Store 10 或 Windows 通用平台。
顺便说一句,GCC 有一个 quasi-similar -march=native,基本上提供了“这个平台”。
“此平台”隐含在平台工具集中。VS 2012 使用默认为_WIN32_WINNT=0x0602(Windows 8)的 Windows 8.0 SDK 。VS 2013 / 2015 使用默认为_WIN32_WINNT=0x0603(Windows 8.1)的 Windows 8.1 SDK 。如果您使用 VS 2015 和 Windows 10 SDK,则默认为_WIN32_WINNT=0x0A00(Windows 10)。
这样做主要是为了 Windows 应用商店/UWP 应用程序的利益,这些应用程序需要最新的值_WIN32_WINNT才能正确构建。对于 Windows 10,该_WIN32_WINNT值不会逐次更新,因此您可以配置要使用的并行 Windows 10 SDK。有关详细信息,请参阅Visual C++ 团队博客。
对于 Windows 桌面应用程序(又名经典 Win32),您应该在构建配置中明确设置您支持的操作系统版本。通常这是在一个pch.h或其他全局头文件中完成的,但也可以通过构建命令行/makefile/vcxproj 完成:
#include <WinSDKVer.h>
#define _WIN32_WINNT 0x0600 // Windows Vista SP2 or later
#include <SDKDDKVer.h>
Run Code Online (Sandbox Code Playgroud)
或者
#include <WinSDKVer.h>
#define _WIN32_WINNT 0x0601 // Windows 7 or later
#include <SDKDDKVer.h>
Run Code Online (Sandbox Code Playgroud)
Windows 8.x SDK 可以针对 Windows Vista SP2、Windows 7、Windows 8.0、Windows 8.1 或更高版本。
如果您需要对 Windows XP SP3 或 Windows Server 2003 SP2 的支持,那么您必须使用选择 Windows 7.1A SDK 的替代平台工具集设置。有关差异的一些说明,请参阅此帖子。
请记住,VS 2015 本身不支持针对 Windows 7 RTM,仅支持 Windows 7 Service Pack 1。
对于 的特定情况GetOverlappedResultEx,我在我的代码中使用了以下模式,该模式支持为下层 Windows 7 以及 UWP/Windows 应用商店构建。
HANDLE hEvent = CreateEventEx( nullptr, nullptr,
CREATE_EVENT_MANUAL_RESET, EVENT_MODIFY_STATE | SYNCHRONIZE );
...
// Read and verify header
OVERLAPPED request = {};
request.hEvent = hEvent;
bool wait = false;
if( !ReadFile( hFile, ..., &request ) )
{
DWORD error = GetLastError();
if ( error != ERROR_IO_PENDING )
return HRESULT_FROM_WIN32( error );
wait = true;
}
DWORD bytes;
#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
BOOL result = GetOverlappedResultEx( hFile, &request, &bytes, INFINITE, FALSE );
#else
if ( wait )
(void)WaitForSingleObject( hEvent, INFINITE );
BOOL result = GetOverlappedResult( hFile, &request, &bytes, FALSE );
#endif
Run Code Online (Sandbox Code Playgroud)
然后,我为每个受支持的平台提供多个静态库版本。请记住,WACK 工具会检查您的 EXE/DLL 导入和导出表,并将标记任何不受支持的 API。因此,您无法选择运行时,并且必须仅引用“Windows 8”版本中受支持的 API。
| 归档时间: |
|
| 查看次数: |
6808 次 |
| 最近记录: |